Verzerrungseffekte
Übersicht

![]() |
s_m_wBetreff: Verzerrungseffekte |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo,
Ich habe mich in den letzten paar Tagen viel mit dem Thema ausseinander gesetzt, jedoch es nicht hinbekommen. Um zu zeigen, was ich denn versuche: Erstbestes Javaapplet, das ich gefunden habe Mein erster Ansatz war ganz naiv einfach eine Heightmap zu generieren und je nachdem die Pixel zu verschieben, so dass eben der gewünschte Effekt auftaucht, aber das hat alles andere als gut geklappt. Gibt es einen besseren Ansatz, oder vielleicht ein Codeschnippsel, was mir helfen könnte? edit: Ich finde es interessant, wie schnell man die Lösung selbst findet, wenn man gerade nach Hilfe fragt. Ich habe das Ausgangsbild über die Heightmap auf das Endbild projeziert, ich muss es aber genau andersrum machen! edit2: Es gibt also Fortschritt. Mein jetziger Code ist folgender: Code: [AUSKLAPPEN] SuperStrict
Global Background:TImage = LoadImage("bild2.png") Global H:TPixmap = LoadPixmap("bild.png") Global Heightmap:Float[,] = ProcessHeightMap(H, 0, 0) Graphics 800,600 While Not KeyHit(KEY_Escape) DrawImageHeightmap(Background,0,0,Heightmap) DrawPixmap H, 300, 0 If (MouseDown(1)) Heightmap = ProcessHeightmap(H, MouseX() - 400, MouseY() - 300) End If Flip Cls Wend Function DrawImageHeightmap(Image:TImage,x:Int,y:Int,Heightmap:Float[,]) Local Xoffset:Int,Yoffset:Int,Shading:Int,c:Int,r:Float,g:Float,b:Float,newc:Int,rfactor:Float,gfactor:Float,bfactor:Float Local lockedImage:TPixmap = LockImage(Image) Local newImage:TPixmap = CopyPixmap(lockedImage) For Local x:Int=1 To lockedImage.width-2 For Local y:Int=1 To lockedImage.height-2 Xoffset = (Heightmap[x-1,y] - Heightmap[x+1,y])*10 Yoffset = (Heightmap[x,y-1] - Heightmap[x,y+1])*10 Shading = Xoffset * 2 If (x - Xoffset < 0 Or x - Xoffset > lockedImage.width - 1) Xoffset = 0 EndIf If (y - Yoffset < 0 Or y - Yoffset > lockedImage.height - 1) Yoffset = 0 EndIf c = ReadPixel(lockedImage, x - Xoffset, y - Yoffset) WritePixel(newImage, x, y, c) Next Next DrawPixmap newImage,x,y UnlockImage Image End Function Function ProcessHeightmap:Float[,] (Pixmap:TPixmap, XOffset:Int, YOffset:Int) Local Color:Float,Map:Float[Pixmap.width,Pixmap.height] For Local x:Int=0 To Pixmap.width-1 For Local y:Int=0 To Pixmap.height-1 Color = (ReadPixel(Pixmap, x, y) Shr 16) & $ff If (x + XOffset > 0 And x + XOffset < Pixmap.width - 1 And y + YOffset > 0 And y + YOffset < pixmap.height - 1) Map[x + XOffset, y + YOffset] = (Color / 255) * 20 - 0.5 EndIf Next Next Return Map End Function Jedoch ist das ganze ein wenig Langsam. Geht es schneller, wenn man davon ausgeht, dass sich die "Heightmap" jeden Frame ändern soll? |
||
Sheep Happens |
![]() |
BlitzMoritz |
![]() Antworten mit Zitat ![]() |
---|---|---|
'hab mir den Code noch nicht so ganz bis ins Detail angeschaut, aber generell ist es nicht realistisch, DrawPixmap-, ReadPixel- und WritePixel-Befehle zu verwenden und interaktive Echtzeit in der Umsetzung zu erwarten. Da deine (im übrigen sehr interessante) Verfremdungsidee Pixel für Pixel berechnen muss, gibt es letztlich wohl keinen echt schnellen Weg ohne Kompromisse.
Schau doch mal in mein Programm für Verzerrungseffekte hinein: BlitzFoto 1.2 Mein Weg dabei ist folgender: - Pixelfarbwerte nur singulär (also z.B. beim Laden) in Arrays einlesen - Bei der interaktiven Bearbeitung nur noch diese fertigen Arrays nutzen (d.h. neue Position berechnen und per 'plot' zeichnen) - Nur ein Ausschnitt des Bildes (also ein Teil der Arrays) in einer Vorschau wiedergeben, deren Größe selbst gewählt werden kann. Der Ausschnitt ist darüberhinaus beweglich und zoombar. Ich nehme an, auch gimp o.a. arbeiten so ähnlich und können interaktiv nur einen Vorschauteil der Verfremdung in mehr oder weniger ruckelnder Echtzeit wiedergeben. |
||
![]() |
DaysShadow |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ist zwar jetzt nur vermutet, aber ich denke mit einem Shader würde das ganze wahrscheinlich recht einfach zu machen sein, das blöde ist halt nur das BMax von sich aus das nicht drin hat, müsstest dir also etwas über OpenGL oder so basteln...
MfG DaysShadow |
||
Blessed is the mind too small for doubt |
![]() |
s_m_w |
![]() Antworten mit Zitat ![]() |
---|---|---|
Erstmal danke für eure antworten, es stellen sich nur einige Probleme:
- Der Zweck, den ich hoffe zu erfüllen ist hauptsächlich Eyecandy in Spielen: Druckwellen, Kraftfeldeffekte und ähnliches die das Spiel grafisch aufpeppen, das heißt eine teilweise Vorschau kommt nicht in Frage. Ich habe solche Effekte schon öfters gesehen und bewundert. - Was sind Shader? edit: Gerade etwas sehr beeindruckendes gefunden, was mir weiterhelfen könnte. Jedoch verstehe ich absolut garnicht, was da gemacht wird. Blickt da jemand durch und kann mir das erklären? ("Bild2.png" muss ein 256² Bild sein) Code: [AUSKLAPPEN] ' Last iteration's tick value
'trancelation from C using SDL to bmax 'original code found at: http://sol.gfxile.net/gp/ch17.html ' by Jari Komppa AKA Sol. Translated by Jesse. SuperStrict ' Screen surface Global gScreen:TPixmap Global GscreenPtr:Int Ptr Global PITCH:Int ' Texture surface Global gTexture:TPixmap Global gTexturePtr:Int Ptr ' Look-up table Global gLut:Short[] ' Distance mask Global gMask:Int[] ' Screen width Const WIDTH:Int = 480 ' Screen height Const HEIGHT:Int = 320 ' Physics iterations per second Const PHYSICSFPS:Int = 100 ' Last iteration's tick value Global gLastTick:Int Function init() Local temp:TPixmap = LoadPixmap("bild2.png") gTexture = ConvertPixmap(temp,PF_RGBA8888) gTexturePtr = Int Ptr(gTexture.pixels) gLut = New Short[WIDTH * HEIGHT * 4] gMask = New Int[WIDTH * HEIGHT * 4] Local i:Int, j:Int Local distance:Int For i = 0 Until HEIGHT * 2 For j = 0 Until WIDTH * 2 Local xdist:Int = j - WIDTH Local ydist:Int = i - HEIGHT ' round distance:Int = Sqr(xdist * xdist + ydist * ydist) ' square 'If (Abs(xdist) > Abs(ydist)) distance = Abs(xdist) Else distance = Abs(ydist) ' diamond 'distance = (Abs(xdist) + Abs(ydist)) / 2 ' flower 'distance :+ (Sin(ATan2(xdist,ydist) * 5)*8)*57.2957795 If (distance <= 0) distance = 1 Local d:Int = distance If (d > 255) d = 255 gMask[i * WIDTH * 2 + j] = d * $010101 distance = (64 * 256 / distance) & $ff Local angle:Int = (((ATan2(Float(xdist), Float(ydist)) / Pi*2) + 1.0) * 128)*0.0174532925 gLut[i * WIDTH * 2 + j] = (distance Shl 8) + angle Next Next End Function Function blend_mul:Int(source:Int, target:Int) Local sourcer:Int = (source Shr 0) & $ff Local sourceg:Int = (source Shr 8) & $ff Local sourceb:Int = (source Shr 16) & $ff Local targetr:Int = (target Shr 0) & $ff Local targetg:Int = (target Shr 8) & $ff Local targetb:Int = (target Shr 16) & $ff targetr = (sourcer * targetr) Shr 8 targetg = (sourceg * targetg) Shr 8 targetb = (sourceb * targetb) Shr 8 Return (targetr Shl 0) | (targetg Shl 8) | (targetb Shl 16) End Function Function render() ' Ask For the time in milliseconds Local tick:Int = MilliSecs() If (tick <= gLastTick) Delay(1) Return EndIf While (gLastTick < tick) ' 'physics' here gLastTick :+ 100 / PHYSICSFPS Wend Local posx:Int = (Sin((tick * 0.000645234)*57.2957795) + 1) * WIDTH / 2 Local posy:Int = (Sin(tick * 0.000445234*57.2957795) + 1) * HEIGHT / 2 Local posx2:Int =(Sin(-tick * 0.000645234*57.2957795) + 1) * WIDTH / 2 Local posy2:Int =(Sin(-tick * 0.000445234*57.2957795) + 1) * HEIGHT / 2 Local i:Int, j:Int For i = 0 Until HEIGHT For j = 0 Until WIDTH Local lut:Int = gLut[(i + posy) * WIDTH * 2 + j + posx] - gLut[(i + posy2) * WIDTH * 2 + j + posx2] Local mask:Int = gMask[(i + posy) * WIDTH * 2 + j + posx] Local mask2:Int = gMask[(i + posy2) * WIDTH * 2 + j + posx2] gScreenPtr[(j) + (i) * PITCH] =.. blend_mul(.. blend_mul(.. gTexturePtr[((lut + tick / 32) & $ff) +.. (((lut Shr 8) + tick / 8) & $ff) *.. (gTexture.pitch/4)],.. mask),.. mask2) Next Next End Function ' Attempt To Create a WIDTHxHEIGHT window with 32bit pixels. Graphics width,height gScreen = CreatePixmap(WIDTH, HEIGHT ,PF_RGBA8888) gScreenPtr = Int Ptr(gScreen.pixels) PITCH = gScreen.pitch/4 init() ' Main loop: loop Forever. Repeat Cls render() DrawPixmap gScreen,0,0 Flip(0) Until KeyDown(KEY_ESCAPE) |
||
Sheep Happens |
![]() |
DaysShadow |
![]() Antworten mit Zitat ![]() |
---|---|---|
Shader: http://de.wikipedia.org/wiki/Shader
Sofern ich es richtig verstanden habe sind Shader kleine Programme die von der Grafikkarte ausgeführt werden und ein Frame(also das derzeitige Bild) verändern können bevor das Bild auf den Bildschirm kommt, dadurch sind sie recht schnell und ermöglichen Echtzeiteffekte. Zu dem Code: Sieht schön aus, habe keine Ahnung wie das funktioniert, aber er zieht zuviel Leistung. Edit: Naja, der Code verzerrt das Bild indem er halt die Pixelkoordinaten durch Berechnungen verändert, das macht er über eine Pixmap, das ist aber in der Regel zu langsam und Leistungsfordernd für einen brauchbaren Echtzeiteinsatz. MfG DaysShadow |
||
Blessed is the mind too small for doubt |
- Zuletzt bearbeitet von DaysShadow am Mi, Dez 23, 2009 0:19, insgesamt einmal bearbeitet
![]() |
s_m_w |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hm, also interpretiere ich es richtig, dass es unmöglich ist, das zu machen, was ich vorhatte? | ||
Sheep Happens |
![]() |
DaysShadow |
![]() Antworten mit Zitat ![]() |
---|---|---|
Nur mit den von BlitzMax gegebenen Mitteln würde ich es behaupten, ja.
MfG DaysShadow |
||
Blessed is the mind too small for doubt |
![]() |
Noobody |
![]() Antworten mit Zitat ![]() |
---|---|---|
Mit BRL.GLGraphics liefert BMax die komplette OGL-API mit - du könntest dir also ohne zusätzliche Module einen Verzerr-Shader basteln.
Der Shader an sich ist meistens in kurzer Zeit geschrieben. Mit GLSL hat man ja eine High Level Shadersprache zur Hand, mit der man sehr effizient Shader programmieren kann. Andererseits ist das Initialisieren und Aktualisieren, das man zum Verwenden und Anzeigen des Shaders benötigt, nicht ganz einfach. Du müsstest dich daher stark mit OGL auseinandersetzen, falls du dich für diesen Weg entscheidest; du müsstest dann auch damit leben, dass je nach dem, wie du sie umsetzt, diese Effekte nicht bei jedem laufen werden. |
||
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun |
AvaGast |
![]() Antworten mit Zitat |
|
---|---|---|
Zitat: ich denke mit einem Shader würde das ganze wahrscheinlich recht einfach zu machen sein
Im Programmablauf um ein Vielfaches schneller auf alle Fälle ... aber einfacher auf keinen Fall. ![]() Und das bezieht sich nicht einmal so sehr auf die Einarbeitung in OpenGL und GLSL. Ein Shaderprogramm ist ne ziemlich enge Zwangsjacke. Das mag etwas paradox klingen, da man Shader ansich direkt mit tollen Grafikmöglichkeiten in super Geschwindigkeit assoziiert - was ja auch richtig ist. ABER vieles was sich mit gewöhnlichem Programmcode recht einfach lösen lässt (wenn auch nicht unbedingt Echtzeit tauglich ![]() ![]() @ s_m_w Meine Grafikengine hat einen sehr einfachen, benutzerfreundlichen Shadersupport. Wenn Du magst kann ich Dir die Module hochladen. Mit GLSL müsstest Du Dich aber auch dann vertraut machen (um den eigentlichen Shadercode zu schreiben). |
||
![]() |
s_m_w |
![]() Antworten mit Zitat ![]() |
---|---|---|
Noobody hat Folgendes geschrieben: Du müsstest dich daher stark mit OGL auseinandersetzen, falls du dich für diesen Weg entscheidest; du müsstest dann auch damit leben, dass je nach dem, wie du sie umsetzt, diese Effekte nicht bei jedem laufen werden.
Das würde mich nicht unbedingt stören, solange es denn bei mir selbst läuft. Ava hat Folgendes geschrieben: @ s_m_w
Meine Grafikengine hat einen sehr einfachen, benutzerfreundlichen Shadersupport. Wenn Du magst kann ich Dir die Module hochladen. Mit GLSL müsstest Du Dich aber auch dann vertraut machen (um den eigentlichen Shadercode zu schreiben). Das ist ein Angebot, das ich gerne annehmen würde |
||
Sheep Happens |
AvaGast |
![]() Antworten mit Zitat |
|
---|---|---|
Schau mal hier: https://www.blitzforum.de/foru...hp?t=33529
Es ist bisher leider noch kein Shader-Beispiel dabei. Ich werde mich bemühen, noch eines anzufertigen. |
||
![]() |
Jan_Ehemaliger Admin |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ach, dieser Effekt ist garnicht so schwer.
Das mit der Highmap ist schon richtig. Du brauchst eine Highmap + Cubemapping. Das gibts bestimmt in Minib3d und ein Beispiel in der Blitzhilfe für Cubemapping. Im Buch Gameprogramming Gems gibt es dann auch noch den Algorhythmus für das Wasser. Lg. Jan_ |
||
between angels and insects |
![]() |
AnniXa |
![]() Antworten mit Zitat ![]() |
---|---|---|
soweit ich weis handelt es sich um blitzmax | ||
|moonForge|
Ich bin Pokémon Meisterin seit 1998! |
![]() |
DaysShadow |
![]() Antworten mit Zitat ![]() |
---|---|---|
Und miniB3D ist ein Modul für eben dieses, nicht wahr? ![]() MfG DaysShadow |
||
Blessed is the mind too small for doubt |
![]() |
AnniXa |
![]() Antworten mit Zitat ![]() |
---|---|---|
ja, das stimmt schon, aber er möchte es doch als spielerei für seine spiele machen :O | ||
|moonForge|
Ich bin Pokémon Meisterin seit 1998! |
![]() |
Jan_Ehemaliger Admin |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ja, und annixa, da kann er dochj trotzdem Minib3d verwenden...
Das was er zeigt in dem Java dings, ist ein Wasser Effekt der mit Cubemapping und minib3d einfach zu machen geht. und das Kann er in seinem Programm doch nutzen! |
||
between angels and insects |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group