RGB-Palette in 32²-Textur / Farbige Beleuchtung mit Dot3

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

aMul

Sieger des Minimalist Compo 01/13

Betreff: RGB-Palette in 32²-Textur / Farbige Beleuchtung mit Dot3

BeitragMi, Jun 04, 2008 20:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Da ich gerade meiner privaten Sprite-Bibliothek(in der Funktionalität vergleichbar mit Draw3D von hectic) ein Beleuchtungssystem, basierend auf Normalmaps, verpassen möchte, stand ich vor dem Problem, wie man farbige Lichter umsetzen kann. Da die Vertex-Farbe schon für das Dot3-Mapping draufgeht, muss man die Farbe irgendwie mit einer Textur erzeugen. Natürlich kann man jetzt einfach eine klitzekleine Textur erzeugen und die jeden Frame entsprechend umfärben. Aber das war mir zu einfach und es würde bei vielen verschiedenen Lichtfarben "zu viel" Speicher brauchen und das ewige Lockbuffer/Unlockbuffer bzw. Writepixel wäre mit Sicherheit auch keine besonders performante Lösung.
Nun musste ich irgendwie die komplette RGB-Palette(man will ja schön flexibel sein) in einer Textur unterbringen. Mit den Millionen von Farben schien es aber keine gute Idee, einfach für jede mögliche Farbe einen Pixel zu benutzen.
Und hier kam mir meine geniale Idee (Razz):
Warum nicht die Grafikkarte die benötigte Farbe interpolieren lassen?
So brauch man für eine Graustufen-Palette zum Beispiel nur zwei Pixel, Schwarz und Weiß. Durch Berechnung der UV-Koordinaten kann man die Grafikkarte ganz einfach den benötigten Grauwert erzeugen lassen.

Nach einer kurzen Überlegung kam ich zu folgender 32x32 Pixel großen Texturen, aus welcher tatsächlich die gesamte RGB-Palette interpoliert werden kann:
user posted image
Der Trick ist, dass es für jeden Rot-Wert einen Block von 4 Pixeln gibt, aus welchem Grün und Blau interpoliert werden können.

Der Code um diese Textur zu erzeugen sieht wie folgt aus:

Code: [AUSKLAPPEN]
Local i, x, y, c, r, g, b, image

image = CreateImage(32, 32)

SetBuffer ImageBuffer(image)

For i = 0 To 255
   x = (i / 16) * 2
   y = (i Mod 16) * 2
   r = i
   
   g = 0
   b = 0
   c = r Shl 16 + g Shl 8 + b
   WritePixel x, y, c
   
   g = 255
   b = 0
   c = r Shl 16 + g Shl 8 + b
   WritePixel x+1, y, c
   
   g = 0
   b = 255
   c = r Shl 16 + g Shl 8 + b
   WritePixel x, y+1, c
   
   g = 255
   b = 255
   c = r Shl 16 + g Shl 8 + b
   WritePixel x+1, y+1, c
Next

SaveImage image, "LightColors.bmp"


Um nun die richtigen UV-Koordinaten zu berechnen kann man einfach folgenden Code benutzen:

Code: [AUSKLAPPEN]
u# = (0.5 + (red / 16) * 2 + green / 256.0) / 32.0
v# = (0.5 + (red Mod 16) * 2 + blue / 256.0) / 32.0


Hier noch eine kleiner Test-Code, um zu beweisen, dass es auch klappt:

Code: [AUSKLAPPEN]
Graphics3D 640, 480, 0, 2

Local cam, mesh, surface, v0, v1, v2, v3, tex

cam = CreateCamera()

mesh = CreateMesh()
surface = CreateSurface(mesh)
EntityFX mesh, 1 + 2

v0 = AddVertex(surface, -2, -2, 5)
v1 = AddVertex(surface, 2, -2, 5)
v2 = AddVertex(surface, 2, 2, 5)
v3 = AddVertex(surface, -2, 2, 5)
AddTriangle(surface, v0, v2, v1)
AddTriangle(surface, v0, v3, v2)

tex = LoadTexture("LightColors.bmp")
EntityTexture mesh, tex, 0, 0

Local u#, v#, r, g, b

SetBuffer BackBuffer()

Repeat
   r = 127 + Sin(MilliSecs() / 2) * 127
   g = 127 + Sin(MilliSecs() / 3) * 127
   b = 127 + Sin(MilliSecs() / 5) * 127
   
   u = (0.5 + (r / 16) * 2 + g / 256.0) / 32.0
   v = (0.5 + (r Mod 15) * 2 + b / 256.0) / 32.0
   
   VertexTexCoords(surface, v0, u, v)
   VertexTexCoords(surface, v1, u, v)
   VertexTexCoords(surface, v2, u, v)
   VertexTexCoords(surface, v3, u, v)
   
   RenderWorld
   Flip 0
   Cls
   Delay 20
Until KeyHit(1)
End


[EDIT]
Was ich ganz vergessen habe: Da die Interpolation von Grafikkarten nicht 100% perfekt ist, kommt es zu leichten Fehlern. Die Stärke dieser ist vermutlich von Grafikkarte zu Grafikkarte unterschiedlich.
Meine Radeon HD3870 interpoliert die Farben mit Abweichungen von maximal +-3 (der Rot-Wert stimmt allerdings immer).
Meiner Meinung nach ist dies aber eine vernachlässigbare Abweichung. In der Praxis lässt sich wohl kein Unterschied bemerken.
[/EDIT]

Um die beschriebene farbige Beleuchtung durch Dot3-Mapping zu bewerkstelligen, muss natürlich noch einiges gemacht werden, aber das ist eine andere Geschichte. Wink

Ich hoffe, dass meine Idee und der Code irgendwem von Nutzen ist.
Vielleicht kommt ja noch jemand auf andere Sachen, die man hiermit anstellen kann.
Wenn ich mein Sprite-Lib aufgerüstet habe, werde ich auf alle Fälle mal ein kleines Video machen und im WIP-Thread vorzeigen.
Bis dahin:

Cheers!
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

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMi, Jun 04, 2008 22:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Das klingt sehr vielversprechend. Ich werde zumindest versuchen das auf meinen aktuellen Vektoreditor zu integrieren. Dieser nutzt DrawQuad3D zur Landschaftsgestalltung mit dem Zusatz, dass eben noch dot3-mapping benutzt wird. Das heisst, dass sich die Landschaft den Lichtverhältnissen anpasst und das ganze etwas mehr plastisch erscheinen lässt.

Hier mal ein Screenshot aus dem Editor: http://www.hectic.de/data/ved_02.png

Eine zusätzliche Einfärbung habe ich noch nicht ausprobiert, hatte schon so genügend Probleme zu beseitigen um es überhaupt soweit zu bringen...
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

aMul

Sieger des Minimalist Compo 01/13

BeitragMi, Jun 04, 2008 23:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Mein Ausgangsproblem war, dass Dot3 + Transparenz nicht mit einem Surface funktioniert, deshalb brauch man für meine Lösung mehrere Surfaces bzw. Meshes. Man muss das Lighting-Mesh dann allerdings auf Blendmode 2 stellen, und mit einer Maske(Specular-Map) die transparenten Flächen ausblenden(=schwarz machen).
Daraus folgt, dass man die Normalmaps wirklich nur noch zur Beleuchtung, nicht mehr für Schatten benutzen kann.
Das ist mein derzeitiges Problem, wenn ich es aber nicht lösen kann werde ich auf Schatten verzichten und nur mit Licht arbeiten müssen.

Für einen Space-Shooter, bei denen die Raumschiffe durch Explosionen rot angestrahlt werden reicht das aber auf alle Fälle Smile
Außerdem kann man die Sprites ja einfach dunkler machen, als ob sie nicht beleuchtet wären, dann sollte das relativ gut aussehen(Und zudem auch realistischer sein, wenn man mal drüber nachdenkt).
Das führt allerdings wieder zu weniger Kontrasten(bzw. vor allem zu langweiligen Farben).
Natürlich könnte man wieder dem "Base-Mesh" auch eine Normalmap verpassen, um ein paar Schatten zu kriegen. Für ein statisches Umgebungslicht wäre sowas praktisch, leider gibt es das dann halt nur in weiß...
Naja, wie dem auch sei, ich möchte nicht zu ausfallend werden, obwohl so ein bisschen Brainstorming sicher nicht schaden kann.

Achja, freut mich, dass du dir die Sache mal - in Verbindung zu deinem Editor - anschaust.
Dieser sieht übrigens, nur so nebenbei, sehr professionell aus, aber mittlerweile erwarte ich nichts anderes mehr von dir 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

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMi, Jun 04, 2008 23:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Jetzt nach weiterem überlegen erkenne ich, dass die Idee einfach genial ist. Ich werde allerdings das ganze noch um ein Alphachannel erweitern müssen und verzichte dafür auch gerne auf den vollen Farbspektrum von jeweils 256 Abstufungen pro Farbkanal. Für mein editor benötige ich sogar nur 4 Abstufungen für jeweils A, R, G und B. Dazu würde also eine Textur von 8x8 Pixel ausreichen.

Problematisch natürlich nach wie vor, dass man keine Transparenz auf dot3 Texturen anwenden kann. Das heisst, dass sich nur ein Farbverlauf zaubern lässt, nicht aber die Textur selbst ausfaden lässt. Das ist aber ein ganz anderes Problem und hat nichts mit dem Code hier selbst zu tun.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

aMul

Sieger des Minimalist Compo 01/13

BeitragMi, Jun 04, 2008 23:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Die 4 Abstufungen hast du allerdings nur in den nicht-interpolierten Farben. Das ist ja der Trick am ganzen.
Aufgrund der zweidimensionalen Art von Texturen kann man sich so zwei Channels aussuchen, die das volle Spektrum abkriegen. Du könntest also mit einer 64*64 großen Textur komplett RGB und 2 bit Alpha unterbringen.
Ich will dir das natürlich nicht aufdrängen, aber ich finde Bunt toll. Mr. Green

Ach, und was genau meinst du mit "Textur ausfaden"?
(Ist mein Thread, ich finde es gehört hier hin 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

hectic

Sieger des IS Talentwettbewerb 2006

BeitragDo, Jun 05, 2008 0:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Das mit dem Verlauf stimmt schon. Ich hab aber im Editor nur 4 Farbstufen vorgesehen, da man sonst zuviel für meinem Geschmack rumspielen würde, was für den Editoreffekt eh unnötig währe.

Hier mal das grad ganz frisch erstellte Minibild: user posted image

Im Editor soll man lediglich bestimmte Bereiche etwas einfärben können. So ähnlich wie es im Spiel Soldat auch der Fall ist.

Mit ausfaden meine ich nicht deine übergezogene Textur, sondern die Grundtextur selbst. Im folgendem Bild kann man das ganz gut in der Mitte/Oben erkennen. Der Boden geht ins transparente über, was das ganze schöner macht. Dieses Bild ist aber noch von meinem alten Editor, der noch kein dot3 machte.

http://www.hectic.de/data/ved_01.png

Mir fällt gerade noch auf, dass man keine Verläufe innerhalb eines Quads machen kann, da diese sich durch alle Facetten der Farbstuffen verlaufen. Hier müsste man sich noch was einfallen lassen. Im Moment fällt mir nur ein, dass man eine weitere Textur benötigen würde, wenn man alle Farben und transparenz erhalten will.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D
 

Dreamora

BeitragDo, Jun 05, 2008 2:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich erkenn in den ganzen überlegungen hier einen recht elementaren Fehler: Während Normalmapping ein gängiges Verfahren ist auf aktuellen Systemen um auf 2D Objekten beleuchtung reinzuzaubern, wird das mit Blitz3D nicht wirklich gehen.

Nicht weil Blitz dafür zu dämlich ist, sondern weil die gängigen Systeme dafür PixelShader nutzen und PerPixel Normalmapping. Blitz jedoch ist FFP und DX7 und hat nur PerVertex Normalmapping. Das heisst die Interpolation läuft auf Basis der Vertices was erzwingt das man nicht unerheblich viele hat speziell bei grösseren Sprites (was mit Pixelshadern egal wäre), wenn man es auch nur einigermassen brauchbar abgestuft haben will.
Das Problem sieht man auch in den Editorscreenshots mit den zick-zack schatten linien die, so vermute ich ma, vom darunterliegenden Meshgitter herrühren.
Mit geschickter Wahl des Gitters kann man das Problem in einem gewissen Masse abfangen (gitternetz parallel zur licht / schatten linie), was jedoch die erzeugung der media nicht ganz unkompliziert macht bzw. einen relativ intelligenten editor verlangt.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

aMul

Sieger des Minimalist Compo 01/13

BeitragDo, Jun 05, 2008 7:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich kann den angesprochenen Fahler nicht ganz nachvollziehen.
Natürlich hat BB(/DX7) keine PixelShader aber solange man die Sprites, wie du ja selber sagst, nicht zu groß macht gibt es da keine Probleme. Aber selbst mit großen Sprites kann es gut aussehen:
user posted image
(nur ein kleiner Test ob meine Trigonometrie stimmt, die Lichtquelle ist oben links)

Wenn sich ein großes Sprite und eine Lichtquelle zu sehr nähern, oder das Licht sogar irgendwo mittig auf dem Sprite sitzt, sieht es teilweise zugegebenermaßen nicht ganz optimal aus.
Wobei es mit einer guten Normalmap doch ganz akzeptabel aussieht, da dann wirklich alle "nach innen gedrehten" Flächen leuchten.
Der Trick ist hier, dass man, bei geringer Entfernung den "Beleuchtungsvektor" anpasst, dass das Licht immer mehr von oben kommt als von der Seite.

Was die zick-zack-Lienen angeht:
Ich denke mal, dass liegt an der Normalmap. Aber falls nicht, dann sieht es ja auch nicht so schlecht aus, dass man deswegen das Spiel nicht spielen würde.

@hectic:
Stimmt, das ist ein gutes Argument für weniger Farben.

Und das ausfaden:
Wenn du die Beleuchtung auf ein Extra-Mesh legst, dann kannst du das ja theoretisch wieder ohne Probleme machen. Allerdings würde das Licht dann nicht mit transparenter werden, was unter Umständen doch komisch aussehen könnte.
Und leider kannst du dafür nicht noch eine dritte Textur benutzen, BB unterstützt ja nur zwei UV-Sets.

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group