Kirjautuminen

Haku

Tehtävät

Oppaat: Grafiikka: Plasmaefekti

Kirjoittaja: peki. Vuosi: 2004.

Lyhyesti

Plasma on hyvin yksinkertainen efekti. Se perustuu suureen taulukkoon, joka täytetään "satunnaisella" kaavalla. Tämän jälkeen se animoidaan paletilla. Usein taulukko on myös varsinaista efektiä suurempi, jotta taulukkoa voidaan liikutella. Useimmiten näitä taulukoita on kaksi tai useampia, ja ne yhdistetään käyttämällä keskiarvoa.

Tällaista yritämme saada aikaan:
Plasma

Kartta

Ensiksi tarvitsemme kaavan, jolla toteuttaa taulukko.
Tässä esimerkki:
func1[i, j] = 64 + 63 * Sin(i / [40 + 10 * Cos(j / 74)]) * Cos(j / [50 + 10 * Sin(i / 60)])
Kaava on täysin tuulestatemmattu ja sen voi korvata omalla. Sen tarkoitus on vain luoda harmaasävykartta, jossa on pehmeitä väriliukuja.

Hyvän funktion pohjana voit käyttää vaikka tätä äsken esittelemääni kaavaa. Jos muutat arvoja edes hiukan, saat aivan uudennäköisen kartan. Variaatioita on siis lähes loputtomasti. Tietysti voit luoda myös alusta oman funktiosi, mutta hienosäätämisessä saattaa silloin kestää kauan.
Perussääntönä kartan luomiseen voin sanoa, että kannattaa käyttää mahdollisimman paljon "aaltoilevia" funktioita kuten siniä ja kosinia.

Luodaan neljä kertaa isompi kartta kuin ruutu on. Voidaan siis liikutella karttaa hienomman efektin aikaansaamiseksi

for (i = 0; i <= ruudunleveys * 4; i++)
    for (j = 0; j <= ruudunkorkeus * 4; j++)
        // satunnainen kaava, jolla saa aikaan pehmeän kartan
        func1[i, j] = 64 + 63 * Sin(i / (40 + 10 * Cos(j / 74))) * Cos(j / (50 + 10 * Sin(i / 60)))

Yksinkertainen paikallaanpysyvä harmaa väriliukujen kokelma ei ole hirveän hieno. On siis tarpeen tehdä palettianimaatio.

Paletti

Tarvitaan 256 värinen paletti, jonka alku- ja loppupää "sopivat yhteen"
Tämä kuva selventää asiaa:

Gradientti

Paletin luominen pseudokoodina. Tämä gradientti on hieman erilainen ja tummempisävyinen kuin kuvassa, mutta sen ei ole tarkoituskaan olla samanlainen.
Aika-muuttuja sisältää plasman päivityskerrat. Sen voi nollata, mutta olen sen jättänyt tässä pois:

for (i = 0; i <= 255; i++)
{
    punainen = 72 + 71 * Cos(i * pii / 128 + aika / 74)  // punaisen värin määrä
    vihreä = 72 + 71 * Sin(i * pii / 128 + aika / 63)    // vihreän värin määrä
    sininen = 72 - 71 * Cos(i * pii / 128 + aika / 81)   // sinisen värin määrä    paletti[i] = RGB(punainen, vihreä, sininen) // laitetaan palettiin
}

Piirtäminen

Piirtäminen hoituu asettamalla paletin avulla kuvan jokainen pikseli vastaamaan kaavalla luotua taulukkoa. Jos taulukoita on useampi kuin yksi, käytetään keskiarvoa. Tässä esimerkissä on kaksi taulukkoa.
Siirtäminen tapahtuu pyörittämällä toista karttaa myötäpäivään ja toista vastapäivään.

while (true)
{
    aika += 20; // tätä lukua saa muokata mielinmäärin, mitä pienempi se on
                // sen sulavampi efektistä tulee.
    for (i = 0; i <= 255; i++)
    {
        punainen = 72 + 71 * Cos(i * pii / 128 + aika / 74)  // punaisen värin määrä
        vihreä = 72 + 71 * Sin(i * pii / 128 + aika / 63)    // vihreän värin määrä
        sininen = 72 - 71 * Cos(i * pii / 128 + aika / 81)   // sinisen värin määrä
        paletti[i] = RGB(punainen, vihreä, sininen) // laitetaan palettiin
    }
     // jokainen pikseli käydään läpi
    for (x = 0; x < ruudunleveys; x++)
    {
        for (y = 0; y < ruudunkorkeus; y++)
        {
            // pyöritetään func1:n sisältämää taulukkoa
            liikutettufunc1 = func1[ruudunleveys * 2 + x + 100 * Cos(aika * pii / 360), ruudunkorkeus * 2 + y + 100 * Sin(aika * pii / 360)]
            // pyöritetään func2:n sisältämää taulukkoa eri suuntaan
            liikutettufunc2 = func2[ruudunleveys * 2 + x + 100 * Sin(aika * pii / 360), ruudunkorkeus * 2 + y + 100 * Cos(aika * pii / 360)]
            // lasketaan keskiarvo
            arvo = (liikutettufunc1 + liikutettufunc2) / 2
            // varmistetaan, ettei tule virhettä
            If (arvo > 255) arvo = 255
            // pikseli näytölle
            näytto[x, y] = paletti[arvo]
        }
    }
}

Linkki toimivaan exeen: http://koti.mbnet.fi/peku1/Plasma.exe
Vaatii windows XP/2000 tai vähintään .net framework 1.0 asennettuna.

Loppusanat

Koodissa on hyvin paljon optimoimisen varaa. Esimerkiksi kaikki trigonometriset funktiot voisi laskea etukäteen ja sijoittaa taulukkoon.
Kaavaa hiemankin muuttamalla efekti muuttuu täysin. Erilaisia muunnoksia on kiva kokeilla.
Toivottavasti pidit tästä oppaasta ja se oli sinulle hyödyllinen.

Olisi varmasti mukavaa katsella muiden versioita tästä efektistä. Jos saat hienon version aikaan, voisitko linkittää sen tähän kommentiksi?
Kielellä ei luonnollisestikaan ole merkitystä.

Pekka Järvinen, 7.7.2004

Kommentit

sooda [17.07.2004 16:32:33]

Lainaa #

Peki tha graffapro. Onpas hieno. Sun pseudokoodi vaan näyttää olevan aika c++:aa :)

flob [17.07.2004 20:11:09]

Lainaa #

Hyvä opas =) Tuon paletin ei kai tarvi olla päistään yhteensopiva?

peki [17.07.2004 21:11:13]

Lainaa #

Ei välttämättä, mutta se tekee efektistä paremman näköisen.

flob [18.07.2004 13:51:59]

Lainaa #

64 + 63 * Sin(i / [40 + 10 * Cos(j / 74)]) * Cos(j / [50 + 10
* Sin(i / 60)]) ... Kaava antaa lukuja väliltä [1, 127]
joten paletista käytetään vain alkuosaa. "Yhteensopivuudella"
ei siis ole merkitystä efektin näyttävyyden kannalta.

Eri asia on tilanteet missä luodaan taulukoita jossa luvut kiertää
niin että 255 jälkeen tulee 0...

peki [18.07.2004 14:15:48]

Lainaa #

Totta. Olet oikeassa. Tuo kaava, joka muodostaa pohjafunktion siis kannattaa tehdä välille 0-255. Se on tuosta suhteellisen helppo muokata.
Edit: Mutta oppaan tarkoitus ei olekkaan antaa muille täysin valmista koodia, vaan idea, jonka avulla muut voivat tehdä omia versioitaan efektistä.
Olet silti oikeassa. Minun olisi pitänyt olla tarkempi.

flob [18.07.2004 16:56:34]

Lainaa #

Onhan tuo oppaan paletti kyllä hirveän käyttökelpoinen
monissa efekteissä=)

tejeez [18.07.2004 20:02:38]

Lainaa #

Tällasta opasta oon oottanuki :)

BlueByte [18.07.2004 22:20:48]

Lainaa #

vb on kakke :8

tejeez [25.07.2004 22:02:12]

Lainaa #

Teinpä vic20:lle jonkulaisen (aika huonon) plasman, http://koodaa.mine.nu/tvt/plasma.prg
(jos koodaa.mine.nu -osoite ei toimi, kokeilkaa esim. tejeez.ath.cx )

moptim [09.11.2006 19:13:00]

Lainaa #

367 tavua, mutta saisko screenshotin? en omista vic20:ta...

tgunner [16.11.2006 09:19:53]

Lainaa #

Voihan sitä yrittää emuloida :)

moptim [10.02.2007 09:28:41]

Lainaa #

Grr. En löydä mistään toimivaa emulaattoria. Pfau Zeh kaatuu aina virheeseen. Sitten jossain oli korruptoitunut paketti. Kaikkialla on vain Pfau Zehiin viittauksia. Ja yhdellä sivulla oli juttua jostain emulaattorista, mutta EI LATAUSLINKKIÄ!

moptim [20.02.2007 15:43:03]

Lainaa #

:D nyt pitäs toimia

Sahrah [20.05.2008 14:42:51]

Lainaa #

päivää herra moptim

Kirjoita kommentti

Huomio! Kommentoi tässä ainoastaan tämän oppaan hyviä ja huonoja puolia. Älä kirjoita muita kysymyksiä tähän. Jos koodisi ei toimi tai tarvitset muuten vain apua ohjelmoinnissa, lähetä viesti keskusteluun.

Muista lukea keskustelun ohjeet.
Tietoa sivustosta