[B3D]2D-Schatten (3D benötigt!)

Übersicht BlitzBasic Codearchiv

Gehe zu Seite 1, 2, 3, 4  Weiter

Neue Antwort erstellen

aMul

Sieger des Minimalist Compo 01/13

Betreff: [B3D]2D-Schatten (3D benötigt!)

BeitragSo, Jun 14, 2009 14:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Normalerweise bin ich nicht so einer, aber da dieser Code wirklich nichts besonderes ist, habe ich aufgrund von Bitten im WIP-Thread das ganze noch einmal überarbeitet und schmeiße es hiermit unters Volk.
Ein Dank geht an Ava, für Inspiration und Idee.
[/Geschwafel]

2D-Schatten - 2 Lichter!
2D-Schatten - 2 Lichter!

(klicken zum vergrößern)

Der Code erzeugt Schatten beliebig vieler Objekte zu einer Lichtquelle, welche sich über die Spielwelt blenden lassen. Schatten und Licht können beide beliebige Farben haben.
Im Prinzip könnte man auch mehrere Lichter benutzen, wenn man diese einzeln in Texturen rendert, zusammenblendet und dann erst als Maske benutzt.
Evtl. werde ich auch noch einen entsprechenden Code schreiben und hochladen.

[EDIT]
Code mit zwei Lichtern ist unten zu finden.

[EDIT]
Auf Anfrage eine kleine Erläuterung des Algorithmus:
user posted image
Jedes Objekt(hier als Beispiel ein Dreieck) besteht aus mehreren Kanten(hier genau drei).
Zu jeder Kante wird ein schwarzes Schatten-Viereck erzeugt(hier... schwarz) welches sich zwei Eckpunkte mit der entsprechenden Kante teilt. Die anderen Beiden Eckpunkte werden auf der Geraden von Licht zum Kanten-Eckpunkt sehr weit außerhalb des Bildschirms platziert(dass die drei Punkte auf einer Geraden liegen ist hoffentlich erkennbar).
So hat man den Schatten berechnen den diese eine Kante erzeugt.
Macht man dies für alle Kanten, sind automatisch alle nicht beleuchteten Bereiche Schwarz.
Hierbei werden wenn Objekte hinter anderen liegen viele Bereiche mehrmals eingefärbt(bzw. entfärbt), aber schwarz ist schwarz. Wink
Diese Schattenmaske kann man dann benutzen um alles auszublenden, was nicht im Licht liegt.
Ich hoffe, mit dieser Erklärung lässt sich etwas anfangen.

Code: [AUSKLAPPEN]
Const SCRW = 800
Const SCRH = 600

Graphics3D SCRW, SCRH, 32, 2

SeedRnd MilliSecs()

Local camera, shadow.TShadow, ms
camera = CreateCamera() ; creates camera to render shadows
CameraClsColor camera, 255, 255, 255

shadow = CreateShadow(0, False) ; initializes shadow
shadow\light\radius = 300 ; set light radius
shadow\light\blu = 0 ; set light color to yellow

CreateRandomObjects(50) ; create some objects to cast shadows

SetBuffer BackBuffer()

Repeat
   ms = MilliSecs()
   
   
   shadow\light\x = MouseX() ;set light position
   shadow\light\y = MouseY()
   DrawShadows(shadow) ; draw light and shadows
   
   RenderWorld ; render
   
   DrawWalls() ; draw walls(slow!)
   
   Text 0, 0, MilliSecs() - ms
   Flip 0
   Delay 17 - MilliSecs() + ms
Until KeyHit(1)

End


Function CreateRandomObjects(n = 50)
   ; creates n random light blocking objects
   Local i, j, x#, y#, a#, e, r#, wall.TWall
   For i = 1 To n
      x = Rnd(SCRW)
      y = Rnd(SCRH)
      a = Rnd(360)
      e = Rand(1, 4)
      e = (e = 1) * 3 + (e = 2) * 4 + (e = 3) * 6 + (e = 4) * 36
      r = Rnd(20, 50)
      For j = 1 To e
         CreateWall(x + Cos(a + j * 360 / e) * r, y + Sin(a + j * 360 / e) * r, x + Cos(a + (j + 1) * 360 / e) * r, y + Sin(a + (j + 1) * 360 / e) * r)
      Next
   Next
End Function

Function DrawWalls()
   ; draws walls
   ;! This function is very slow! Do not use for purposes other than testing or debugging!
   Local wall.TWall
   For wall = Each TWall
      Line wall\x1, wall\y1, wall\x2, wall\y2
   Next
End Function

;! ------------------------------------------------------------------------------- !;
;! ------------------------------- LIB STARTS HERE ------------------------------- !;
;! ------------------------------------------------------------------------------- !;


Type TWall
   ; a line that blocks light
   Field x1#
   Field y1#
   Field x2#
   Field y2#
End Type

Type TShadow
   ; a shadow object, needed to cast shadows
   Field mesh
   Field surface
   Field light.TLight
   Field red
   Field grn
   Field blu
   Field backface
End Type

Type TLight
   ; a light, needed to cast shadows
   Field x#
   Field y#
   Field radius#
   Field red
   Field grn
   Field blu
End Type

Function CreateWall.TWall(x1#, y1#, x2#, y2#)
   ; creates a TWall from (x1|y1) to (x2|y2)
   ; returns that TWall
   Local wall.TWall
   wall = New TWall
   wall\x1 = x1
   wall\y1 = y1
   wall\x2 = x2
   wall\y2 = y2
   Return wall
End Function

Function CreateShadow.TShadow(parent = 0, backfaceCulling = True, alignToCamera = True)
   ; creates a TShadow and TLight
   ; returns that TShadow
   ; parent: any entity or 0
   ; backfaceCulling: makes walls opaque from both sides
   ; alignToCamera: aligns shadows to the 2D coordinate system
   Local shadow.TShadow
   shadow = New TShadow
   shadow\mesh = CreateMesh(parent)
   shadow\surface = CreateSurface(shadow\mesh)
   EntityFX shadow\mesh, 1 + 2 + 16 * backfaceCulling
   EntityBlend shadow\mesh, 2
   shadow\backface = backfaceCulling
   shadow\light = New TLight
   shadow\light\radius = 100
   shadow\light\red = 255
   shadow\light\grn = 255
   shadow\light\blu = 255
   If alignToCamera
      AlignShadowMeshToCamera(shadow)
   EndIf
   Return shadow
End Function

Function AlignShadowMeshToCamera(shadow.TShadow, distance# = 100)
   ; aligns shadows to the 2D coordinate system
   ; shadow: TShadow to align
   ; distance: mesh and therefor triangle distance to the camera
   PositionEntity shadow\mesh, - distance / 2, distance * GraphicsHeight() / GraphicsWidth() / 2, distance / 2
   ScaleEntity shadow\mesh, distance / GraphicsWidth(), - distance / GraphicsWidth(), 1
End Function

Function DrawShadows(shadow.TShadow, drawLight = True, clear = True, LightDetail = 36)
  ; draws shadows
   ; shadow: TShadow to draw
   ; drawLight: draws light
   ; clear: clears previous shadows (highly recommended!)
   ; lightDetail: triangles used for light mesh
   Local wall.TWall, v0, v1, v2, v3
   Local lx#, ly#, lr#, nx#, ny#, d#
   Local x#, y#, x2#, y2#
   lx = shadow\light\x
   ly = shadow\light\y
   lr = shadow\light\radius
   If clear
      ClearSurface(shadow\surface)
   EndIf
   If drawLight
      DrawShadowLight(shadow, LightDetail)
   EndIf
   For wall = Each TWall
      If (wall\x1 > lx - lr Or wall\x2 > lx - lr) And (wall\x1 < lx + lr Or wall\x2 < lx + lr) And (wall\y1 > ly - lr Or wall\y2 > ly - lr) And (wall\y1 < ly + lr Or wall\y2 < ly + lr)
         nx = wall\y2 - wall\y1
         ny = wall\x1 - wall\x2
         d = Sqr(nx * nx + ny * ny)
         nx = nx / d
         ny = ny / d
         d = nx * (wall\x1 - lx) + ny * (wall\y1 - ly)
         If d > -lr And d < lr * shadow\backface
            x = (wall\x1 - lx) * 10000 + lx
            y = (wall\y1 - ly) * 10000 + ly
            x2 = (wall\x2 - lx) * 10000 + lx
            y2 = (wall\y2 - ly) * 10000 + ly
            v0 = AddVertex(shadow\surface, wall\x1, wall\y1, 0)
            v1 = AddVertex(shadow\surface, wall\x2, wall\y2, 0)
            v2 = AddVertex(shadow\surface, x, y, 0)
            v3 = AddVertex(shadow\surface, x2, y2, 0)
            VertexColor(shadow\surface, v0, shadow\red, shadow\grn, shadow\blu)
            VertexColor(shadow\surface, v1, shadow\red, shadow\grn, shadow\blu)
            VertexColor(shadow\surface, v2, shadow\red, shadow\grn, shadow\blu)
            VertexColor(shadow\surface, v3, shadow\red, shadow\grn, shadow\blu)
            AddTriangle(shadow\surface, v0, v3, v2)
            AddTriangle(shadow\surface, v0, v1, v3)
         EndIf
      EndIf
   Next
End Function

Function DrawShadowLight(shadow.TShadow, detail)
   ; draws light
   ; shadow: shadow which light is to be drawn
   ; detail: triangles used for light mesh
   Local i, v0, v1, v2, v3, v4, v5, v6
   v0 = AddVertex(shadow\surface, shadow\light\x, shadow\light\y, 0)
   VertexColor(shadow\surface, v0, shadow\light\red, shadow\light\grn, shadow\light\blu)
   v1 = AddVertex(shadow\surface, shadow\light\x + shadow\light\radius, shadow\light\y, 0)
   VertexColor(shadow\surface, v1, shadow\red, shadow\grn, shadow\blu)
   v4 = AddVertex(shadow\surface, shadow\light\x + 1000000, shadow\light\y, 0)
   VertexColor(shadow\surface, v4, shadow\red, shadow\grn, shadow\blu)
   v2 = v1
   v5 = v4
   For i = 1 To detail - 1
      v3 = AddVertex(shadow\surface, shadow\light\x + Cos(i * 360 / detail) * shadow\light\radius, shadow\light\y + Sin(i * 10) * shadow\light\radius, 0)
      v6 = AddVertex(shadow\surface, shadow\light\x + Cos(i * 360 / detail) * 1000000, shadow\light\y + Sin(i * 10) * 1000000, 0)
      VertexColor(shadow\surface, v3, shadow\red, shadow\grn, shadow\blu)
      VertexColor(shadow\surface, v5, shadow\red, shadow\grn, shadow\blu)
      AddTriangle(shadow\surface, v0, v2, v3)
      AddTriangle(shadow\surface, v2, v5, v6)
      AddTriangle(shadow\surface, v2, v6, v3)
      v2 = v3
      v5 = v6
   Next
   AddTriangle(shadow\surface, v0, v2, v1)
   
   AddTriangle(shadow\surface, v2, v4, v1)
   AddTriangle(shadow\surface, v2, v6, v4)
End Function


[EDIT]
Hier das ganze nochmal mit zwei Lichtern.
Der Code ist zwar nicht so schön organisiert wie der obere, aber Interessierte werden sich schon zurechtfinden.
Die Geschwindigkeit hat durch das Hinzufügen eines weiteren Lichtes leider sehr gelitten.
Hier ließe sich sicherlich einiges rausholen, wenn man Hardware-beschleunigt auf die Texturen rendert.
Generell kann man mit B3D hier allerdings keine Wunder erwarten.

Mit einem Rechtsklick lassen sich übrigens die ganzen 2D-Linien ausblenden, was auch schon für einen ordentlichen Geschwindigkeitsboost sorgt

Code: [AUSKLAPPEN]
Const SCRW = 800
Const SCRH = 600

Graphics3D SCRW, SCRH, 32, 2

SeedRnd MilliSecs()

Local camera, shadow.TShadow, shadow2.TShadow, ms
camera = CreateCamera() ; creates camera to render shadows
CameraClsColor camera, 255, 255, 255

shadow = CreateShadow() ; initializes shadow
shadow\light\radius = 300 ; set light radius
shadow\light\blu = 0 ; set light color to yellow

shadow2 = CreateShadow() ; initializes shadow
shadow2\light\radius = 300 ; set light radius
shadow2\light\red = 0 ; set light color to blue
shadow2\light\grn = 0

Local shadow1_tex, shadow2_tex, mesh, surface, v0, v1, v2, v3

shadow1_tex = CreateTexture(1024, 1024)
shadow2_tex = CreateTexture(1024, 1024)
TextureBlend shadow2_tex, 3

mesh = CreateMesh()
surface = CreateSurface(mesh)
PositionEntity mesh, - SCRW / 2 - 0.5, SCRH / 2 + 0.5, SCRW / 2
ScaleEntity mesh, 1, -1, 1
v0 = AddVertex(surface, 0, 0, 0)
v1 = AddVertex(surface, 0, 1024, 0)
v2 = AddVertex(surface, 1024, 1024, 0)
v3 = AddVertex(surface, 1024, 0, 0)
VertexTexCoords(surface, v0, 0, 0)
VertexTexCoords(surface, v1, 0, 1)
VertexTexCoords(surface, v2, 1, 1)
VertexTexCoords(surface, v3, 1, 0)
AddTriangle(surface, v0, v3, v2)
AddTriangle(surface, v0, v2, v1)

EntityFX mesh, 1 + 2
EntityBlend mesh, 2

EntityTexture mesh, shadow1_tex, 0, 0
EntityTexture mesh, shadow2_tex, 0, 1


CreateRandomObjects() ; create some objects to cast shadows

SetBuffer BackBuffer()

Local render2D = True

Repeat
   ms = MilliSecs()
   
   If MouseHit(2)
      render2D = 1 - render2D
   EndIf
   
   shadow\light\x = MouseX() ;set light position
   shadow\light\y = MouseY()
   DrawShadows(shadow) ; draw light and shadows
   RenderToTexture(shadow1_tex)
   ClearSurface shadow\surface
   
   shadow2\light\x = SCRW / 2 + Cos(MilliSecs() / 20) * 100 ;set light position
   shadow2\light\y = SCRH / 2 + Sin(MilliSecs() / 20) * 100
   DrawShadows(shadow2)
   RenderToTexture(shadow2_tex)
   ClearSurface shadow2\surface
   
   RenderWorld ; render
   
   If render2D
      DrawWalls() ; draw walls(slow!)
      Oval shadow\light\x - 5, shadow\light\y - 5, 10, 10, 0
      Oval shadow2\light\x - 5, shadow2\light\y - 5, 10, 10, 0
   EndIf
   
   Text 0, 0, MilliSecs() - ms
   Flip 0
   Delay 17 - MilliSecs() + ms
Until KeyHit(1)

End


Function CreateRandomObjects(n = 50)
   ; creates n random light blocking objects
   Local i, j, x#, y#, a#, e, r#, wall.TWall
   For i = 1 To n
      x = Rnd(SCRW)
      y = Rnd(SCRH)
      a = Rnd(360)
      e = Rand(1, 4)
      e = (e = 1) * 3 + (e = 2) * 4 + (e = 3) * 6 + (e = 4) * 36
      r = Rnd(20, 50)
      For j = 1 To e
         CreateWall(x + Cos(a + j * 360 / e) * r, y + Sin(a + j * 360 / e) * r, x + Cos(a + (j + 1) * 360 / e) * r, y + Sin(a + (j + 1) * 360 / e) * r)
      Next
   Next
End Function

Function DrawWalls()
   ; draws walls
   ;! This function is very slow! Do not use for purposes other than testing or debugging!
   Local wall.TWall
   For wall = Each TWall
      Line wall\x1, wall\y1, wall\x2, wall\y2
   Next
End Function

Function RenderToTexture(texture)
   ; renders and than copies the backbuffer into the texturebuffer
   RenderWorld
   CopyRect 0, 0, SCRW, SCRH, 0, 0, BackBuffer(), TextureBuffer(texture)
End Function

;! ------------------------------------------------------------------------------- !;
;! ------------------------------- LIB STARTS HERE ------------------------------- !;
;! ------------------------------------------------------------------------------- !;


Type TWall
   ; a line that blocks light
   Field x1#
   Field y1#
   Field x2#
   Field y2#
End Type

Type TShadow
   ; a shadow object, needed to cast shadows
   Field mesh
   Field surface
   Field light.TLight
   Field red
   Field grn
   Field blu
   Field backface
End Type

Type TLight
   ; a light, needed to cast shadows
   Field x#
   Field y#
   Field radius#
   Field red
   Field grn
   Field blu
End Type

Function CreateWall.TWall(x1#, y1#, x2#, y2#)
   ; creates a TWall from (x1|y1) to (x2|y2)
   ; returns that TWall
   Local wall.TWall
   wall = New TWall
   wall\x1 = x1
   wall\y1 = y1
   wall\x2 = x2
   wall\y2 = y2
   Return wall
End Function

Function CreateShadow.TShadow(parent = 0, backfaceCulling = True, alignToCamera = True)
   ; creates a TShadow and TLight
   ; returns that TShadow
   ; parent: any entity or 0
   ; backfaceCulling: makes walls opaque from both sides
   ; alignToCamera: aligns shadows to the 2D coordinate system
   Local shadow.TShadow
   shadow = New TShadow
   shadow\mesh = CreateMesh(parent)
   shadow\surface = CreateSurface(shadow\mesh)
   EntityFX shadow\mesh, 1 + 2 + 16 * backfaceCulling
   ;EntityBlend shadow\mesh, 2
   shadow\backface = backfaceCulling
   shadow\light = New TLight
   shadow\light\radius = 100
   shadow\light\red = 255
   shadow\light\grn = 255
   shadow\light\blu = 255
   If alignToCamera
      AlignShadowMeshToCamera(shadow)
   EndIf
   Return shadow
End Function

Function AlignShadowMeshToCamera(shadow.TShadow, distance# = 100)
   ; aligns shadows to the 2D coordinate system
   ; shadow: TShadow to align
   ; distance: mesh and therefor triangle distance to the camera
   PositionEntity shadow\mesh, - distance / 2, distance * GraphicsHeight() / GraphicsWidth() / 2, distance / 2
   ScaleEntity shadow\mesh, distance / GraphicsWidth(), - distance / GraphicsWidth(), 1
End Function

Function DrawShadows(shadow.TShadow, drawLight = True, clear = True, LightDetail = 36)
  ; draws shadows
   ; shadow: TShadow to draw
   ; drawLight: draws light
   ; clear: clears previous shadows (highly recommended!)
   ; lightDetail: triangles used for light mesh
   Local wall.TWall, v0, v1, v2, v3
   Local lx#, ly#, lr#, nx#, ny#, d#
   Local x#, y#, x2#, y2#
   lx = shadow\light\x
   ly = shadow\light\y
   lr = shadow\light\radius
   If clear
      ClearSurface(shadow\surface)
   EndIf
   If drawLight
      DrawShadowLight(shadow, LightDetail)
   EndIf
   For wall = Each TWall
      If (wall\x1 > lx - lr Or wall\x2 > lx - lr) And (wall\x1 < lx + lr Or wall\x2 < lx + lr) And (wall\y1 > ly - lr Or wall\y2 > ly - lr) And (wall\y1 < ly + lr Or wall\y2 < ly + lr)
         nx = wall\y2 - wall\y1
         ny = wall\x1 - wall\x2
         d = Sqr(nx * nx + ny * ny)
         nx = nx / d
         ny = ny / d
         d = nx * (wall\x1 - lx) + ny * (wall\y1 - ly)
         If d > -lr And d < lr * shadow\backface
            x = (wall\x1 - lx) * 10000 + lx
            y = (wall\y1 - ly) * 10000 + ly
            x2 = (wall\x2 - lx) * 10000 + lx
            y2 = (wall\y2 - ly) * 10000 + ly
            v0 = AddVertex(shadow\surface, wall\x1, wall\y1, 0)
            v1 = AddVertex(shadow\surface, wall\x2, wall\y2, 0)
            v2 = AddVertex(shadow\surface, x, y, 0)
            v3 = AddVertex(shadow\surface, x2, y2, 0)
            VertexColor(shadow\surface, v0, shadow\red, shadow\grn, shadow\blu)
            VertexColor(shadow\surface, v1, shadow\red, shadow\grn, shadow\blu)
            VertexColor(shadow\surface, v2, shadow\red, shadow\grn, shadow\blu)
            VertexColor(shadow\surface, v3, shadow\red, shadow\grn, shadow\blu)
            AddTriangle(shadow\surface, v0, v3, v2)
            AddTriangle(shadow\surface, v0, v1, v3)
         EndIf
      EndIf
   Next
End Function

Function DrawShadowLight(shadow.TShadow, detail)
   ; draws light
   ; shadow: shadow which light is to be drawn
   ; detail: triangles used for light mesh
   Local i, v0, v1, v2, v3, v4, v5, v6
   v0 = AddVertex(shadow\surface, shadow\light\x, shadow\light\y, 0)
   VertexColor(shadow\surface, v0, shadow\light\red, shadow\light\grn, shadow\light\blu)
   v1 = AddVertex(shadow\surface, shadow\light\x + shadow\light\radius, shadow\light\y, 0)
   VertexColor(shadow\surface, v1, shadow\red, shadow\grn, shadow\blu)
   v4 = AddVertex(shadow\surface, shadow\light\x + 1000000, shadow\light\y, 0)
   VertexColor(shadow\surface, v4, shadow\red, shadow\grn, shadow\blu)
   v2 = v1
   v5 = v4
   For i = 1 To detail - 1
      v3 = AddVertex(shadow\surface, shadow\light\x + Cos(i * 360 / detail) * shadow\light\radius, shadow\light\y + Sin(i * 10) * shadow\light\radius, 0)
      v6 = AddVertex(shadow\surface, shadow\light\x + Cos(i * 360 / detail) * 1000000, shadow\light\y + Sin(i * 10) * 1000000, 0)
      VertexColor(shadow\surface, v3, shadow\red, shadow\grn, shadow\blu)
      VertexColor(shadow\surface, v5, shadow\red, shadow\grn, shadow\blu)
      AddTriangle(shadow\surface, v0, v2, v3)
      AddTriangle(shadow\surface, v2, v5, v6)
      AddTriangle(shadow\surface, v2, v6, v3)
      v2 = v3
      v5 = v6
   Next
   AddTriangle(shadow\surface, v0, v2, v1)
   
   AddTriangle(shadow\surface, v2, v4, v1)
   AddTriangle(shadow\surface, v2, v6, v4)
End Function


[EDIT]
Letzteren Code geändert, sodass die Textur pixelgenau dargestellt wird.

[EDIT]
Tippfehler korrigiert, der beide Codes etwa zwei bis dreimal schneller machen sollte.

[EDIT]
Funktion DrawShadows() optimiert, benötigt jetzt nur noch etwa ein Drittel der Zeit.
  • Zuletzt bearbeitet von aMul am Sa, Jun 20, 2009 16:27, insgesamt 10-mal bearbeitet

TimBo

BeitragSo, Jun 14, 2009 14:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi aMul,

dürfte ich Fragen , wie deine Enigne Funktioniert, also wie sie vorgeht, so schnell so geilen schatten zu machen Smile

Ich hätte nur den Ansatz mit Writepixelfast, aber wie hast du das gemacht ?

Viele Grüße
TimBo
mfg Tim Borowski // CPU: Ryzen 2700x GPU: Nvidia RTX 2070 OC (Gigabyte) Ram: 16GB DDR4 @ 3000MHz OS: Windows 10
Stolzer Gewinner des BCC 25 & BCC 31
hat einen ersten Preis in der 1. Runde beim BWInf 2010/2011 & 2011/12 mit BlitzBasic erreicht.

Chrise

BeitragSo, Jun 14, 2009 14:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Schon alleine die Befehle VertexTriangle dürften darauf hindeuten, dass das ganze mit 3D-Objekten arbeitet Wink
Llama 1 Llama 2 Llama 3
Vielen Dank an Pummelie, der mir auf seinem Server einen Platz für LlamaNet bietet.

TimBo

BeitragSo, Jun 14, 2009 14:58
Antworten mit Zitat
Benutzer-Profile anzeigen
ja das steht ja schon in dem Namen des Threards, aber wie macht man das in 3D ?

also will nicht den Code erklärt bekommen (viel zu viel arbeit) nur einfach den Ansatz dahinter erfragen.

Viele Grüße
TimBo
mfg Tim Borowski // CPU: Ryzen 2700x GPU: Nvidia RTX 2070 OC (Gigabyte) Ram: 16GB DDR4 @ 3000MHz OS: Windows 10
Stolzer Gewinner des BCC 25 & BCC 31
hat einen ersten Preis in der 1. Runde beim BWInf 2010/2011 & 2011/12 mit BlitzBasic erreicht.

aMul

Sieger des Minimalist Compo 01/13

BeitragSo, Jun 14, 2009 15:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Das ganze ist 3D-beschleunigt, Timbo, weshalb es sehr schnell ist(wenn man DrawWalls() rausnimmt).
Im Prinzip erstelle ich nur zu jeder Wand ein schwarzes Viereck, mit zwei Eckpunkten an den Ecken der Wand und den beiden anderen sehr sehr weit weg, aber auf der gleichen Geraden wie Lichtquelle und Wand-Eckpunkte.
Wenn die Erklärung nicht reicht, kann ich auch noch ein kleines Bildchen erstellen um das zu verdeutlichen.
Sag einfach ob du es verstanden hast. Wink
Panic Pong - ultimate action mashup of Pong and Breakout <= aktives Spiele-Projekt, Downloads mit vielen bunten Farben!
advASCIIdraw - the advanced ASCII art program <= aktives nicht-Spiele-Projekt, must-have für ASCII/roguelike/dungeon-crawler fans!
Alter BB-Kram: ThroughTheAsteroidBelt - mit Quelltext! | RGB-Palette in 32²-Textur / Farbige Beleuchtung mit Dot3 | Stereoskopie in Blitz3D | Teleport-Animation Screensaver
 

Ava

Gast

BeitragSo, Jun 14, 2009 15:01
Antworten mit Zitat
Very Happy Ich wäre sehr neugierig, ob man mit dieser Technik auch bei B3D wirklich mehrere Lichter realisieren kann.

Das war ehrlich gesagt die grösste Herausforderung für mich. In meiner Engine verwende ich Max- und Min-Blendmodes, bei denen jeweils nur die hellsten bzw. dunkelsten Pixel beim Übereinanderzeichnen bestehen bleiben. Damit lassen sich quasi alle Schatten entfernen, die irgendwo im Licht liegen. Aber so etwas gibt es meines Wissens ja in B3D nicht. Also wenn Du da einen anderen Lösungsweg findest, wäre das sehr spannend für mich! Smile

TimBo

BeitragSo, Jun 14, 2009 15:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke für deine Erklärung, aMul.

So ganz verstehen tuhe ich das nicht , wäre echt nett eine Skizze zu haben , damit ich die Wirkungsweise von dem Cube besser verstehen könnte.

Thanks !!

PS: sieht echt genial aus !

Grüße
TimBo
mfg Tim Borowski // CPU: Ryzen 2700x GPU: Nvidia RTX 2070 OC (Gigabyte) Ram: 16GB DDR4 @ 3000MHz OS: Windows 10
Stolzer Gewinner des BCC 25 & BCC 31
hat einen ersten Preis in der 1. Runde beim BWInf 2010/2011 & 2011/12 mit BlitzBasic erreicht.

aMul

Sieger des Minimalist Compo 01/13

BeitragSo, Jun 14, 2009 15:38
Antworten mit Zitat
Benutzer-Profile anzeigen
TimBo und Ava, beide bitte einmal oben gucken. Wink
Panic Pong - ultimate action mashup of Pong and Breakout <= aktives Spiele-Projekt, Downloads mit vielen bunten Farben!
advASCIIdraw - the advanced ASCII art program <= aktives nicht-Spiele-Projekt, must-have für ASCII/roguelike/dungeon-crawler fans!
Alter BB-Kram: ThroughTheAsteroidBelt - mit Quelltext! | RGB-Palette in 32²-Textur / Farbige Beleuchtung mit Dot3 | Stereoskopie in Blitz3D | Teleport-Animation Screensaver

ToeB

BeitragSo, Jun 14, 2009 15:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich finds im prinzip sehr schön, nur sind viele shatten seehr unötig das sie gemalt werden. z.b. beim kreis, da muss nicht jedes "Wall" erinzeln berechnet werden. Betrachte dazu ein Object als ganzes. So z.b. der Kreis, hat einen mittelpunkt und einen radius. Jetzt misst man den winkel vom Licht zur Kreismitte. Wenn man zu dem winkel "90" addiert hat man eine Gerade die senkrecht zum winkel steht. Und wenn man -90 rechnet, hatt man die gleiche gerade nur zur anderen seite gedreht. Jetzt prüft man, wo die beiden geraden sich mit dem Kreis schneiden (oder einfach den radius nehmen). Das sind dann die Punkte, wo der Schatten ansetzt. Wenn du jetzt von den beiden Punkten den winkel zum Licht misst, musst du nur noch den Shatten in diesen beiden winkeln weiter zeichnen . Also brauchst du ingesammt nur 2 Dreiecke... Und nicht 50 ... :

Code: [AUSKLAPPEN]
Graphics 800,600,16,2
SetBuffer BackBuffer()

SeedRnd MilliSecs()

Type o
   Field midx,midy
   Field radius
   Field s.shadow
End Type


Type light
   Field x,y
End Type

Type shadow
   Field x1,y1
   Field x2,y2
   Field x3,y3
   Field x4,y4
End Type

For i = 1 To 25
   o.o = New o
   o\midx = Rand(100,700)
   o\midy = Rand(100,500)
   o\radius = Rand(25,50)
   o\s = New shadow
Next

Global light.light = New light


Repeat
   
   light\x = MouseX()
   light\y = MouseY()
   
   For l.light = Each light
      ;Für jedes Licht jedes Object prüfen...
      For o.o = Each o
         ;Winkel zum kreis
         winkel# = ATan2(o\midy-l\y,o\midx-l\x)
         ;Punkte 1+2 für Schatten ausrechnen
         o\s\x1 = o\midx + Cos(winkel+90)*o\radius
         o\s\y1 = o\midy + Sin(winkel+90)*o\radius
         winkel1# = ATan2(o\s\y1-l\y,o\s\x1-l\x)
         
         o\s\x2 = o\midx + Cos(winkel-90)*o\radius
         o\s\y2 = o\midy + Sin(winkel-90)*o\radius
         winkel2# = ATan2(o\s\y2-l\y,o\s\x2-l\x)
         ;Punkte 3+4 für Schatten ausrechnen
         o\s\x3 = o\midx + Cos(winkel2) * (800*2)
         o\s\y3 = o\midy + Sin(winkel2) * (800*2)
         
         o\s\x4 = o\midx + Cos(winkel1) * (800*2)
         o\s\y4 = o\midy + Sin(winkel1) * (800*2)
      Next
   Next
   
   ;Malen
   Color 255,255,0
   For l.light = Each light
      Oval l\x-5,l\y-5,10,10
   Next
   Color 255,0,0
   For o.o = Each o
      Oval o\midx-o\radius,o\midy-o\radius,o\radius*2,o\radius*2,0
   Next
   Color 100,100,100
   LockBuffer BackBuffer()
   For s.shadow = Each shadow
      Line s\x1,s\y1,s\x2,s\y2
      Line s\x2,s\y2,s\x3,s\y3
      Line s\x3,s\y3,s\x4,s\y4
      Line s\x4,s\y4,s\x1,s\y1
      
      Line s\x1,s\y1,s\x3,s\y3
      Line s\x2,s\y2,s\x4,s\y4
   Next
   UnlockBuffer BackBuffer()
   Flip
   Cls
Until KeyHit(1)
End



mfg ToeB
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art
SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek
Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt!

aMul

Sieger des Minimalist Compo 01/13

BeitragSo, Jun 14, 2009 15:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Du hast vollkommen recht, ToeB.
Allerdings ist es nach meiner Erfahrung bei weitem schneller einfach einen Haufen Quads zu zeichnen als die CPU mit komplizierten Berechnungen zu belasten.

Die von dir gezeigte Möglichkeit habe ich nun gerade nicht ausprobiert, alle anderen meiner Versuche die Anzahl an Polys zu verringern haben aber zu weniger FPS geführt(selbst wenn ich teilweise nur noch ein paar anstatt ein paar hundert Quads hatte.

Wenn man wirklich Kreise Schatten werfen lassen möchte mag deine Methode natürlich dennoch schneller sein. Vielleicht werde ich das testen und einbauen, vielleicht auch nicht. Wink
Panic Pong - ultimate action mashup of Pong and Breakout <= aktives Spiele-Projekt, Downloads mit vielen bunten Farben!
advASCIIdraw - the advanced ASCII art program <= aktives nicht-Spiele-Projekt, must-have für ASCII/roguelike/dungeon-crawler fans!
Alter BB-Kram: ThroughTheAsteroidBelt - mit Quelltext! | RGB-Palette in 32²-Textur / Farbige Beleuchtung mit Dot3 | Stereoskopie in Blitz3D | Teleport-Animation Screensaver

Chrise

BeitragSo, Jun 14, 2009 15:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Frag mich nicht warum, aber bei mir wird angezeigt, dass es mit über 400 FPS läuft. Und trotzdem ruckelt es wie sau ^^
Llama 1 Llama 2 Llama 3
Vielen Dank an Pummelie, der mir auf seinem Server einen Platz für LlamaNet bietet.

aMul

Sieger des Minimalist Compo 01/13

BeitragSo, Jun 14, 2009 16:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Das ist keine FPS Zahl, das zeigt an, wie viele Millisekunden der letzte Frame gedauert hat.
Dementsprechend hast du gerade mal 2.5 FPS Razz

Ohne Shader kann man leider nicht viel mehr machen(außer direkt auf Textur rendern oder Textur verkleinern, keine Ahnung wie viel das bringt).
Panic Pong - ultimate action mashup of Pong and Breakout <= aktives Spiele-Projekt, Downloads mit vielen bunten Farben!
advASCIIdraw - the advanced ASCII art program <= aktives nicht-Spiele-Projekt, must-have für ASCII/roguelike/dungeon-crawler fans!
Alter BB-Kram: ThroughTheAsteroidBelt - mit Quelltext! | RGB-Palette in 32²-Textur / Farbige Beleuchtung mit Dot3 | Stereoskopie in Blitz3D | Teleport-Animation Screensaver

Chrise

BeitragSo, Jun 14, 2009 16:06
Antworten mit Zitat
Benutzer-Profile anzeigen
XD
das erklärt natürlich einiges. Dann muss ich aber dazu sagen, dass die AVAGFX Engine um einiges schneller war ^^
Aber aussehen tut deines auch sehr gut Smile
Llama 1 Llama 2 Llama 3
Vielen Dank an Pummelie, der mir auf seinem Server einen Platz für LlamaNet bietet.

Nicdel

BeitragSo, Jun 14, 2009 16:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Juhu, 4 FPS! Allerdings mit meinem wirklich schlechten Laptop... Schöne Sache.
Desktop: Intel Pentium 4 2650 Mhz, 2 GB RAM, ATI Radeon HD 3850 512 MB, Windows XP
Notebook: Intel Core i7 720 QM 1.6 Ghz, 4 GB DDR3 RAM, nVidia 230M GT, Windows 7

Goodjee

BeitragSo, Jun 14, 2009 16:12
Antworten mit Zitat
Benutzer-Profile anzeigen
ist es eventuell schneller wenn man alle triangles nur einmal am anfang erstellt und nur jeden durchlauf 2 vertices pro wall verschiebt?
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/

aMul

Sieger des Minimalist Compo 01/13

BeitragSo, Jun 14, 2009 16:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Interessanter Gedanke, Goodjee. Das werde ich testen müssen.
Ich weiß, dass es keinen Unterschied macht ob man alle Vertices verschiebt oder neu erstellt, aber hier halbiert sich der Aufwand ja. Wirklich eine gute Idee, Danke!
Panic Pong - ultimate action mashup of Pong and Breakout <= aktives Spiele-Projekt, Downloads mit vielen bunten Farben!
advASCIIdraw - the advanced ASCII art program <= aktives nicht-Spiele-Projekt, must-have für ASCII/roguelike/dungeon-crawler fans!
Alter BB-Kram: ThroughTheAsteroidBelt - mit Quelltext! | RGB-Palette in 32²-Textur / Farbige Beleuchtung mit Dot3 | Stereoskopie in Blitz3D | Teleport-Animation Screensaver

Tankbuster

BeitragSo, Jun 14, 2009 17:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hätte es so ähnlich gemacht. Ich hätte anstatt ein Mesh mit x Texturen, x Meshes mit je einer Textur erstellt und dann bei allen Meshs BlendMode 3 eingestellt.

Das hätte einfach den Vorteil, dass man bestimmte Lichter ausschalten könnte, indem man einfach das Mesh mit HideEntity versteckt Wink (und natürlich das Rendern dieses Lichtes dann auslassen kann)
Ist nicht so umständlich, wie die ganze Textur mit der Maskcolor zu übermalen Wink

Außerdem hast du nur 8 Texturebenen, was maximal 8 Lichter ermöglicht. Ich will jetzt nicht behaupten, dass mein PC mehr als 8 solcher Lichter flüssig darstellen kann, aber ich weiß ja nicht, wie es bei anderen aussieht.
Twitter
Download Jewel Snake!
Windows|Android

aMul

Sieger des Minimalist Compo 01/13

BeitragSo, Jun 14, 2009 17:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Und wieder hat einer recht. Razz
Allerdings benötigt diese Methode noch einen Renderschritt mehr, da man letzten Endes ein Mesh mit BlendMode 2 über den Rest rendern muss, darum kommt man nicht herum.
Panic Pong - ultimate action mashup of Pong and Breakout <= aktives Spiele-Projekt, Downloads mit vielen bunten Farben!
advASCIIdraw - the advanced ASCII art program <= aktives nicht-Spiele-Projekt, must-have für ASCII/roguelike/dungeon-crawler fans!
Alter BB-Kram: ThroughTheAsteroidBelt - mit Quelltext! | RGB-Palette in 32²-Textur / Farbige Beleuchtung mit Dot3 | Stereoskopie in Blitz3D | Teleport-Animation Screensaver

ozzi789

BeitragSo, Jun 14, 2009 19:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Rechtsclick => 13 ms
ned schlecht Smile
0x2B || ! 0x2B
C# | C++13 | Java 7 | PHP 5

Goodjee

BeitragSo, Jun 14, 2009 20:11
Antworten mit Zitat
Benutzer-Profile anzeigen
jo, ohne den 2dquatsch ist es bei mir realtimefähig
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/

Gehe zu Seite 1, 2, 3, 4  Weiter

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group