dynamic Lightning

Spiele, Demos, Grafikzeug und anderes unterhaltendes.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: dynamic Lightning

Beitrag von STARGÅTE »

@Stargate:
Ich glaube ich habe deine Idee noch nich so richtig verstanden. Wenn ich quasi die Dreiecke berechne an die Licht hinkommt und dann da eine Textur drüberlege, hätte ich zwat das Problem gelöst, das ich mehrere Lichtquellen benutzen kann. Die so entstanden Lichtkegel würden aber vom Farbverlauf total verzerrt sein und es würde ziemlich hässlich und nicht wirklich nach Licht aussehen.
Du hast recht, wenn du die Textur nicht an das Dreieck anpasst.
Noch mal etwas detailierter:
Ein Sprite3D besteht aus einem Mesh mit 2 Dreiecken und einer Textur mit 4 Koordinaten.
Im Normalfall binden die beiden Dreicke ein Quadrat und die Texturkoordinaten sind 0,0; 1,0; 1,1 und 0,1.
Wenn du nun das Sprite3D verzerrst, dann musst zu logischerweise auch die Texturkoordinaten verändern.
Das geht nicht direkt in PB, sonden nur mit der im Link angegeben DX9-Struktur.
Hier noch mal ein Link von mir: PB_DX9Sprite - Textur-Kachelung - Sprite3D-Färbung
Wenn du also so ein langgezogenes Dreieck hast, was auch noch "verzerrt" ist, dann musst du eben nur die Texturkoordinaten anpassen, und schon wird das Licht wieder richtig angezeigt.
Am einfachstes wäre es, wenn du das Licht als Kreis aufbaust, und dann immer von 0.5,0.5 ausgehst (als Lichtzentrum) und dann relativ zu den Dreieckskoordinaten die Texturkoordinaten angibst.

Ich hoffe es ist nun etwas klarer wie die Idee ist, ansonsten kann ich dir auch noch mal ein kleines Beispiel schreiben (wenn ich Zeit hab)
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Re: dynamic Lightning

Beitrag von Kukulkan »

Hallo,
oh... well?! hat geschrieben:@Kukulkan:
Ich mal erst das Licht un schneide dann den Schatten wieder weg.
Nicht ganz.

Ich würde so vorgehen:
1) Hintergrund zeichnen (recht dunkel)
2) Schatten mit einer Standard-Textur und Fläche (nur gedreht und gezerrt) für die Objekte zeichnen (abdunkeln per Alpha-Textur)
3) Objekte Zeichnen
4) Licht selbst zeichnen (aufhellen der darunter liegenden Farben)

So können sich Schatten und Lichter addieren. Auch werden Objekte durch das Licht heller. Ich denke, das wäre auch performanter. Nachteil: die Schatten werden physikalisch wohl nicht ganz korrekt sein.

Grüße,

Kukulkan
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: dynamic Lightning

Beitrag von STARGÅTE »

Um mal meine Ausführungen zu visualisieren, hab ich mal einen kleinen Beispielcode geschrieben, wie das mit den Dreiecken funktionieren könnte.

Bild

DisplayLightCone() zeichnet ein Dreieck-Sprite3D mit den Koordianten X,Y und die beiden Polarkoordinaten 1 und 2
DisplayLight() verlangt hier die Koordianten des Lichtzentrums und ein Array aus Ecken, an denen "sich etwas ändert" (was du vermutlich eh hast).
Außerdem hab ich unten noch etwas bewegung hineingebracht.
Wie man/du siehst, wird das ganze Licht "perfekt" dargestellt, obwohl aus aus vielen Dreiecken besteht.
Die Berechnungen (Sin, Cos) könnne natürlich noch ausgelagert werden, um es zu beschleunigen.

Code: Alles auswählen

Structure DX9Vertex
	X.f
	Y.f
	Z.f
	Rhw.f
	Color.l
	Tu.f
	Tv.f
EndStructure  

Structure DX9
	TexRes.i
	Vertice.DX9Vertex[4]
	TmpVertice.DX9Vertex[4]
	Width.l
	Height.l
	RealWidth.l
	RealHeight.l
	Angle.f
	Transformed.l
EndStructure

Structure Corner
	Radius1.f
	Radius2.f
	Angle.f
EndStructure

Procedure DisplayLightCone(Sprite3D.i, X.f, Y.f, Angle1.f, Length1.f, Angle2.f, Length2.f, MaxLength.f=386.0)
	Protected *DX9.DX9 = IsSprite3D(Sprite3D)
	Protected I1=1, I2=2
	With *DX9
		\Transformed = 1
		\Vertice[0]\X = X
		\Vertice[0]\Y = Y
		\Vertice[0]\Tu = 0.5
		\Vertice[0]\Tv = 0.5
		\Vertice[3]\X = X
		\Vertice[3]\Y = Y
		\Vertice[3]\Tu = 0.5
		\Vertice[3]\Tv = 0.5
		If Angle1 > Angle2
			Swap I1, I2
		EndIf
		\Vertice[I1]\X = X+Cos(Angle1)*Length1
		\Vertice[I1]\Y = Y+Sin(Angle1)*Length1
		\Vertice[I2]\X = X+Cos(Angle2)*Length2
		\Vertice[I2]\Y = Y+Sin(Angle2)*Length2
		\Vertice[I1]\Tu = 0.5+Cos(Angle1)*Length1/MaxLength*0.5
		\Vertice[I1]\Tv = 0.5+Sin(Angle1)*Length1/MaxLength*0.5
		\Vertice[I2]\Tu = 0.5+Cos(Angle2)*Length2/MaxLength*0.5
		\Vertice[I2]\Tv = 0.5+Sin(Angle2)*Length2/MaxLength*0.5
		DisplaySprite3D(Sprite3D, 0, 0)
	EndWith
EndProcedure

Procedure DisplayLight(Sprite3D.i, X.f, Y.f, Array Corner.Corner(1), MaxLength.f=386.0)
	Protected Size.i = ArraySize(Corner())
	Protected I.i
	For I = 0 To Size
		DisplayLightCone(Sprite3D, X, Y, Corner(I)\Angle, Corner(I)\Radius1, Corner((I+1)%(Size+1))\Angle, Corner(I)\Radius2, MaxLength)
	Next
EndProcedure



InitSprite()
InitSprite3D()

Enumeration
	#Window
	#Sprite
	#Sprite3D
EndEnumeration

OpenWindow(#Window, 0, 0, 800, 600, "ScreenTitle", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Window), 0, 0, WindowWidth(#Window), WindowHeight(#Window), 0, 0, 0)

CreateSprite(#Sprite, 256, 256, #PB_Sprite_Texture)
StartDrawing(SpriteOutput(#Sprite))
	For R = 127 To 1 Step -1
		Gray = Pow(1-r/127.0, 2)*255
		Circle(128, 128, R, RGB(Gray, Gray, Gray))
	Next
StopDrawing()
CreateSprite3D(#Sprite3D, #Sprite)

Dim Corner.Corner(10)
RandomSeed(5)
For I = 0 To 10
	Corner(I)\Angle = Radian(I*36)
	Corner(I)\Radius1 = Random(256)+128
	Corner(I)\Radius2 = Random(256)+128
Next

Repeat
	
	Repeat
		
		Select WindowEvent()
			Case #PB_Event_CloseWindow
				End
			Case #Null
				Break
		EndSelect
		
	ForEver
	
	ClearScreen(0)
	
	StartDrawing(ScreenOutput())
		For X = 0 To 799
			Line(X,0,1,600,RGB(X*128/799,0,128-X*128/799))
		Next
	StopDrawing()
	
	If Start3D()
		Sprite3DBlendingMode(5,2)
		Corner(3)\Radius1 = 256+Sin(ElapsedMilliseconds()*0.001)*128
		Corner(4)\Angle = Radian(4*36+Sin(ElapsedMilliseconds()*0.001)*18)
		DisplayLight(#Sprite3D, 400, 300, Corner())
		Stop3D()
	EndIf
	
	FlipBuffers()
	
Until WindowEvent() = #PB_Event_CloseWindow
PS: Ich könnte ja gleich mal eine Prozedur schreiben wie DisplayPolygonSprite3D() bei der ein Sprite3D mit der angegebenen Polygon-Maske gezeichnet wird.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
oh... well?!
Beiträge: 98
Registriert: 21.07.2010 10:46
Computerausstattung: Intel Pentium D 2,8 GHz
2 GB RAM
ATI RADEON X700 SE

Zweitrechner :
Intel Pentium M 1,6 GHz
1 GB RAM
Intel 82852/82855 GM/GME Graphics Controller (64 MB)

Re: dynamic Lightning

Beitrag von oh... well?! »

wow, danke Stargate!
hätte ohne deinen Code wahrscheinlich ewig gebraucht das zu verstehen und umzusetzten.
Jetzt werd ich mich mal dran machen das umzusetzten.
Bin immer wieder fasziniert davon wie sauber man Code schreiben kann :allright: .
Bild it's Monkey Buissness
Homepage
facebook
Benutzeravatar
oh... well?!
Beiträge: 98
Registriert: 21.07.2010 10:46
Computerausstattung: Intel Pentium D 2,8 GHz
2 GB RAM
ATI RADEON X700 SE

Zweitrechner :
Intel Pentium M 1,6 GHz
1 GB RAM
Intel 82852/82855 GM/GME Graphics Controller (64 MB)

Re: dynamic Lightning

Beitrag von oh... well?! »

Also ich hab deinen Code jetzt mal ausführlich getestet.
Mir is aufgefallen, dass ich - selbst wenn ich einfach nur deinen Code im Compiler ausführe - ein par überblendete oder ausgelassene Pixel an den Schnittstellen zwischen den Lichtkegeldreiecken bekomme. Komischerweise ist das auf deinem Screenshot nicht der Fall.
Ich hab das Testprogramm auch auf 2 verschiedenen Rechner getestet und hatte beides mal das Problem.
Das Einzige was ich zu deinem Quelletext ergänzt hab ist die Radian() Procedur, weil die noch im Quelltext gefehlt hat

Code: Alles auswählen

Procedure.f Radian(x.f)
   ProcedureReturn x/180*#PI
EndProcedure
Aber daran kanns doch eigentlich nicht liegen?
Muss ich ein neueres DirectX benutzten?
Benutze PB 4.40.

Achja hier ein Screenshot:
Bild
Bild it's Monkey Buissness
Homepage
facebook
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: dynamic Lightning

Beitrag von STARGÅTE »

Der Code wie ich ihn gepostet habe ist eigentlich nur für DX9, denn unter DX7 ist die Struktur anders.

Diese doppelt belegten Pixel dürften eigentlich nur entstehen, wenn die Vertex-Koordinaten keine Floats sind.
In diesem Fall werden aber Floats übergeben, sodass es keine Fehler (auf Grund der unterschiedlichen Gerade) entstehen dürften.

PS Habe hier n ATI Grafikkarte und du ?

PS2: Ich würde dir aber raten auf 4.60 zu updaten.

EDIT: Auf dem Screen sind ja wirklich nur einzelnen problemstellen, dass ist allerdings etwas merkwürdig.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
oh... well?!
Beiträge: 98
Registriert: 21.07.2010 10:46
Computerausstattung: Intel Pentium D 2,8 GHz
2 GB RAM
ATI RADEON X700 SE

Zweitrechner :
Intel Pentium M 1,6 GHz
1 GB RAM
Intel 82852/82855 GM/GME Graphics Controller (64 MB)

Re: dynamic Lightning

Beitrag von oh... well?! »

Hab auf dem einen Rechner ne ATI Radion X700 Se.
Der andere Rechner is nen Netbook mit nem Intel Graphic Media Accelerator (das is der integrierte Graphickern von Intel-Atom Prozessoren)

Wenn man unter Compiler-Options keine Eintrag in "Library-Subsystems" hat, dann läuft die Anwendung unter DirectX 7 oder? was muss ich für directX 9 eintragen?

kann leider nich auf PB 4.60 updaten weil ich keine Version hab bei der die Updates mitbezahlt sind. :(
Zuletzt geändert von oh... well?! am 09.12.2011 23:35, insgesamt 1-mal geändert.
Bild it's Monkey Buissness
Homepage
facebook
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: dynamic Lightning

Beitrag von STARGÅTE »

Ich weiß leider nicht mehr wie es unter 4.4 war, aber ich glaube da war DX9 schon Default.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
oh... well?!
Beiträge: 98
Registriert: 21.07.2010 10:46
Computerausstattung: Intel Pentium D 2,8 GHz
2 GB RAM
ATI RADEON X700 SE

Zweitrechner :
Intel Pentium M 1,6 GHz
1 GB RAM
Intel 82852/82855 GM/GME Graphics Controller (64 MB)

Re: dynamic Lightning

Beitrag von oh... well?! »

Achja, ich hab die Punkte nich in Radiantenform (Winkel und radius) sonder direkt in x und y. Ich weis schon wie man die umrechnet,aber die umzurechnen würde über cos() wieder rechenzeit brauchen. könnte man deine Procedure So anpassen das DisplayLight() nach Eckpunten in Koardinatenform verlang und am besten nich als Array sonder als Liste... oder wäre da wieder das Problem das man die Punkte im/gegen den Uhrzeigersinn sortieren müsste und dann eh wieder von Koardinaten zu Radiantenform(wenn das so heist) umrechnen muss?

Andererseit dürften so ca 120 cos() Rechnungen pro Sekunde auch nich groß ins Gewicht fallen oder?
Bild it's Monkey Buissness
Homepage
facebook
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: dynamic Lightning

Beitrag von STARGÅTE »

Jo, das du n Liste mit X,Y hast hatte ich mir schon gedacht.
Das diese auch nicht unbedingt sortiert sind stellt ein Problem dar.

Eine Hin und wieder Rückrechung wäre aber auch quatsch.

Ich würde dir mal jetzt n Prozedure schreiben, die dann eine Liste mit X,Y verlangt.
Ich denke mal, dass ich die "Sortierung" direkt bei der Anzeige vornehmen könnte, indem einfach schritt für schritt geguckt wird, ob doch noch n Dreieck mehr sein muss.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Antworten