Problem mit Meshterraintextur

Übersicht BlitzBasic Blitz3D

Neue Antwort erstellen

 

schalli

Betreff: Problem mit Meshterraintextur

BeitragMo, Mai 10, 2010 22:05
Antworten mit Zitat
Benutzer-Profile anzeigen
user posted image
Ich habe ein Meshterrain gemacht (in B3D). Es funktioniert mit einer Heightmap. Allerdings sind funktioniert das Licht darauf nicht so richtig und die Textur wird auch nicht richtig angezeigt, sondern nur verschwommen. Andere hatten das Problem auch schon (Ja, ich habe die Suche benutzt!!!), aber ihre Lösungen habe ich nicht verstanden. Es hatte irgendetwas mit "Normalen" zu tun, was das genau ist, weiß ich aber nicht.

Achso, das ist der Code zur Erzeugung, vielleicht ist da ein Fehler:
Code: [AUSKLAPPEN]
Function mtrr(tsix,tsiz,timg)
  mesh = CreateMesh()
  brus = CreateBrush()
  BrushTexture brus,tex
  surf = CreateSurface(mesh,brus)

  SetBuffer ImageBuffer(timg)
  LockBuffer ImageBuffer(timg)
  For z = 0 To (tsiz)
    For x = 0 To (tsix)
      rgb = ReadPixelFast(x,z)
      y# = Float((rgb And $FF0000) / $10000)
      y# = y# * (4.0/255.0)

      terrmap(x,z,0) = AddVertex(surf, x,y#,z)
      terrmap(x,z,1) = AddVertex(surf, x,y#,z)

      If (x>0) And (z>0) Then
        AddTriangle(surf, terrmap(x, z, 0), terrmap(x-1, z, 0), terrmap(x-1, z-1, 0))
        AddTriangle(surf, terrmap(x, z, 1), terrmap(x, z-1, 1), terrmap(x-1, z-1, 1))
      EndIf
    Next
  Next
  UnlockBuffer ImageBuffer(timg)
  SetBuffer BackBuffer()

  UpdateNormals mesh
  FlipMesh mesh
  ScaleMesh mesh, 0.25,1,0.25

  EntityFX mesh,16
  EntityPickMode mesh, 2
  Return mesh
End Function
Theovention - meine Homepage
 

Krischan

BeitragDi, Mai 11, 2010 11:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Das mit der Textur ist recht einfach - Du hast keine Texturkoordinaten (U/V) gesetzt:

AddVertex(surf, x,y#,z)

Das kannst Du z.B. so machen:

u#=x*1.0/tsix
v#=z*1.0/tsiz
AddVertex(surf,x,y,z,u,v)

Das mit den Normals liegt vermutlich am Meshaufbau, versuche mal aus dieser Demo zu lernen (Funktion CreatePatch) und nehme eine Heightmap, die 2^n+1 gross ist, also nicht z.B. 32x32 sondern 33x33:

Code: [AUSKLAPPEN]
Graphics3D 800,600,32,2

Global GameSpeed%=60
Global Screenwidth%=GraphicsWidth()
Global Screenheight%=GraphicsHeight()
Global FramePeriod%=1000/GameSpeed
Global FrameTime%=MilliSecs()-FramePeriod
Global DeltaTimeOld%

hm=LoadImage("heightmap.bmp")
tx=LoadTexture("grass.png")

mesh=CreatePatch(32,hm,tx)
ScaleMesh mesh,16,16,16
EntityFX mesh,2
light=CreateLight(1)

cam=CreateCamera()
MoveEntity cam,8,8,-2
CameraRange cam,0.1,1000
CameraClsColor cam,150,200,255

MoveMouse 400,300

While Not KeyHit(1)
   
   ; Frametween calculation
   Local FrameElapsed%,FrameTicks%,FrameTween#,t%
   Repeat FrameElapsed=MilliSecs()-FrameTime Until FrameElapsed
   FrameTicks=FrameElapsed/FramePeriod
   FrameTween=Float(FrameElapsed Mod FramePeriod)/Float(FramePeriod)
   
   ; Frametween loop
   For t=1 To FrameTicks
      
      ; Frametween Captureworld
      FrameTime=FrameTime+FramePeriod : If t=FrameTicks Then CaptureWorld
      
      If KeyHit(57) Then wf=1-wf : WireFrame wf
      
      FreeCam(cam,85,0.1)
      
   Next
   
   RenderWorld
   
   Flip 0
   
Wend

End


Function CreatePatch(size%=32,heightmap%,tex%)
   
   Local x%,z%,h%,c%
   Local vx#,vz#,u#,v#,vertex%
   Local v0%,v1%,v2%,v3%
   
   Local mesh%=CreateMesh()
   Local brush%=CreateBrush() : BrushTexture brush,tex
   Local surf%=CreateSurface(mesh,brush)
   Local buffer%=ImageBuffer(heightmap)
   
   LockBuffer buffer
   
   For z=0 To size
      
      For x=0 To size
         
         ; calculate vertex coordinates / texture coordinates
         vx=1.0/size*x
         vz=1.0/size*z
         u=x*1.0/size
         v=z*1.0/size
         
         h=(ReadPixelFast(x,z,buffer) And $ff0000)/$10000
         
         
         ; place vertex
         vertex=AddVertex(surf,vx,h/512.0,vz,u,v)
         
         ; set vertex color and texture coordinates
         VertexColor surf,vertex,255,255,255,1
         
         ; set triangles
         If z<size And x<size Then
            
            v0=x+((size+1)*z)
            v1=x+((size+1)*z)+(size+1)
            v2=(x+1)+((size+1)*z)
            v3=(x+1)+((size+1)*z)+(size+1)
            
            AddTriangle(surf,v0,v1,v2)
            AddTriangle(surf,v2,v1,v3)
            
         EndIf
         
      Next
      
   Next
   
   UnlockBuffer buffer
   
   UpdateNormals mesh
   
   Return mesh
   
End Function

Function FreeCam(camera%,maxpitch#=85.0,movespeed#,rotspeed#=16.666,rotfloat#=8.0)
   
   Local movex#,movez#,dx#,dy#,dk#,dt%,t%
   Local pitch#
   
   ; Arrows = Move
   movex=KeyDown(205)-KeyDown(203)
   movez=KeyDown(200)-KeyDown(208)
   
   ; smooth movement
   t=MilliSecs() : dt=t-DeltaTimeOld : DeltaTimeOld=t : dk=Float(dt)/rotspeed
   dx=(Screenwidth/2-MouseX())*0.01*dk : dy=(Screenheight/2-MouseY())*0.01*dk
   TurnEntity camera,-dy,dx*0.1*dk*rotfloat,0
   
   ; limit pitch
   pitch=EntityPitch(camera,1) : If pitch>maxpitch Then pitch=maxpitch Else If pitch<-maxpitch Then pitch=-maxpitch
   
   ; rotate and move
   RotateEntity camera,pitch,EntityYaw(camera,1),0,1   
   MoveEntity camera,movex*movespeed,0,movez*movespeed
   
End Function
 

schalli

BeitragDi, Mai 11, 2010 15:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke für den Tipp mit U und V. Ich habe es ausprobiert und es klappt! Man muss es allerdings genau anderherum machen. Wenn ich x*0.25 nehme, dann wird die Textur einmal pro vier Vertices aufgetragen. Das andere probiere ich später nochmal.
Theovention - meine Homepage
 

Krischan

BeitragDi, Mai 11, 2010 15:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Du kannst die UV-Koordinaten auf dem gesamten Mesh ruhig im Bereich von 0...1 lassen (wie in meinem Beispiel 1.0/size*x), die Textur kannst Du dann immer noch mit ScaleTexture skalieren.
 

schalli

BeitragFr, Mai 14, 2010 10:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Meshterrain selber klappt jetzt gut. Very Happy
Aber ich habe noch eine Frage:
Wenn ich jetzt Multitexturen einbauen will, dann könnte ich Tiles einsetzen. Mein Frage ist, was sind diese Tiles genau? Teile ich das Terrain dann z.B. in 10x10 Surfaces auf, und jedes bekommt eine eine eigene Textur?
Gibt es vielleicht noch andere, bessere Methoden.
Theovention - meine Homepage
 

Krischan

BeitragFr, Mai 14, 2010 10:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Welche Art von Multitexturen?

- Megatextur aufgeteilt in kleinere Einzeltexturen (so wie in BlitzTiles) mit Detailtextur
- Texture Alpha, also einzelne Texturen wie Gras, Sand, Feld ineinandergeblendet

In Blitz3D ist das zweite nicht so einfach da wir hier noch mit DirectX 7 arbeiten. Ausserdem sollte man nicht zu viele Surfaces haben (also z.B. 32x32 Tiles mit je 32x32 Vertices auf je einer Surface = 1024 Surfaces, zu viel!). Ein Beispiel zu Texture Alpha kannst Du Dir hier ansehen:

Meshterrain Texture Splatting und Normal Lighting

user posted image
 

schalli

BeitragFr, Mai 14, 2010 10:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Das normale, eingebaute Multitexturing meinte ich nicht, damit bekommt man ja höchstens 4 Texturen hin. Ich hatte eher an die Sache mit den Megatexturen gedacht. Dein zweites Beispiel schaue ich mir noch mal an.
Theovention - meine Homepage
 

Krischan

BeitragFr, Mai 14, 2010 10:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Also bei BlitzTiles habe ich das so gemacht (Beispiel Monkey Island Map):

- Heightmap im Terragen-Format (wegen 16bit Präzision) mit 2049x2049er Auflösung
- Colormap in gleicher Pixelauflösung so dass 1 Pixel die Farben eines Vertex repräsentiert
- Megatexture in 4096x4096er Auflösung

Die Karte und die Megatexture werden in 8x8=64 Tiles zerschnitten. Jedes Tile hat dann (je nach Qualität der Quadtree-Reduzierung) ca. 16x16 Vertices und ich glaube je drei Surfaces (Megatexture+zwei Detailmaps). Die Megatexture-Tiles haben dann 4096/8=512x512 Pixel Auflösung. Die Ränder kannst Du dir anschauen, wenn Du in der INI-Datei der Map "ShowSeams=1" setzt:

user posted image

Allerdings muss man die gegenüberliegender Ränder noch aneinander angleichen (Vertexcolor, Normals usw...) sonst gibt es unschöne Übergänge.

Man kann auch grössere Megatextures nehmen, aber irgendwann geht das so auf die Performance dass man es bei 4096x4096 belässt. Nachteil ist, dass aus der Ego-Perspektive (hier: der Zwerg) alles nicht besonders detailliert aussieht, aus der Vogelperspektive hingegen viel besser ist. Eine Mischung aus beiden wäre vermutlich besser (Quadtree/Tiles für weitere Entfernung, Texture Alpha für Nahbereich), aber das ist komplizierter als es klingt.

Neue Antwort erstellen


Übersicht BlitzBasic Blitz3D

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group