Prvi koraci u 3D Processing-u

Lekcija 12 od 14 · Processing

Do sada smo u Processing-u crtali dvodimenzionalne objekte kao što su linije, pravougaonici, kružnice i mnogouglovi. U ovoj lekciji napravićemo prvi korak ka trodimenzionalnoj grafici. Naučićemo kako se aktivira P3D renderer, kako se crtaju prvi 3D objekti i na koji način možemo da ih pomeramo i rotiramo.

Šta ćemo naučiti u ovoj lekciji?
  • aktiviranje 3D režima rada (P3D)
  • crtanje osnovnih 3D tela
  • korišćenje funkcije translate()
  • rotaciju objekata
  • osnovne razlike između 2D i 3D grafike

Šta je P3D?

Podrazumevano, Processing koristi dvodimenzionalni renderer. U tom režimu možemo crtati samo objekte u ravni ekrana. Ako želimo da koristimo trodimenzionalnu grafiku, potrebno je da uključimo P3D renderer.

size(800, 600, P3D);

Treći parametar funkcije size() govori Processing-u da će koristiti trodimenzionalni prikaz. Od tog trenutka možemo koristiti funkcije kao što su:

  • box()
  • sphere()
  • rotateX()
  • rotateY()
  • rotateZ()
Važno!

Ako zaboravite da navedete P3D, funkcije za crtanje trodimenzionalnih objekata neće raditi kako očekujete.
P3D renderer

P3D renderer

Processing koristi poseban renderer koji omogućava crtanje trodimenzionalnih objekata.

Razlika između 2D i 3D grafike

2D i 3D grafika

U 3D prostoru objekti imaju širinu, visinu i dubinu.

Processing P3D prozor

3D radni prostor

P3D omogućava prikaz objekata u trodimenzionalnom prostoru.

Prvi 3D program

Počećemo od najjednostavnijeg mogućeg primera. Program crta jednu kocku u centru prozora.

void setup() {
    size(800, 600, P3D);
}

void draw() {
    background(220);

    translate(width / 2, height / 2);

    box(150);
}

Funkcija box() crta kocku čija je stranica jednaka zadatoj vrednosti. Pošto je koordinatni početak u gornjem levom uglu prozora, pomoću funkcije translate() pomeramo koordinatni sistem u centar ekrana.

Eksperiment
  • Povećajte veličinu kocke na 250.
  • Smanjite veličinu na 50.
  • Pomerite kocku ulevo promenom funkcije translate().

Koordinatni sistem u 3D

U dvodimenzionalnoj grafici koristili smo dve ose:

  • X — horizontalna osa
  • Y — vertikalna osa

U trodimenzionalnoj grafici dodaje se još jedna osa:

  • Z — dubina prostora.

Na početku nije potrebno da pamtite u kom smeru raste Z osa. Mnogo je važnije da shvatite da svaki objekat sada ima položaj određen pomoću tri koordinate:

(x, y, z)
Napomena

U narednim primerima koristićemo funkciju translate(x,y,z) kako bismo pomerali objekte po sve tri ose.
Koordinatni sistem u 3D

Koordinatni sistem

Položaj svakog objekta određuje se koordinatama (x, y, z).

Translate u 3D

translate()

Objekat možemo pomerati po svim osama prostora.

3D kocka

box()

Najjednostavniji trodimenzionalni objekat u Processing-u.

Pomeranje objekta u prostoru

Funkcija translate() može da primi tri parametra.

translate(150, 100, -100);

box(120);

Prvi parametar određuje pomeranje po X osi. Drugi parametar određuje pomeranje po Y osi. Treći parametar određuje pomeranje po Z osi. Na taj način objekat možemo postaviti na željeno mesto u prostoru.

Probajte sami
  • Promenite vrednost X koordinate.
  • Promenite vrednost Y koordinate.
  • Menjajte Z koordinatu i posmatrajte promene.
U sledećem delu

Naučićemo kako da rotiramo objekte pomoću funkcija:
  • rotateX()
  • rotateY()
  • rotateZ()
Zatim ćemo dodati osvetljenje i nacrtati više 3D objekata u istoj sceni.

Rotacija 3D objekata

Jedna od najvećih prednosti trodimenzionalne grafike jeste mogućnost rotiranja objekata oko različitih osa. U 2D grafici mogli smo da rotiramo objekat samo u ravni ekrana, dok u 3D prostoru postoje tri nezavisne ose rotacije.

  • rotateX() – rotacija oko X ose
  • rotateY() – rotacija oko Y ose
  • rotateZ() – rotacija oko Z ose
Napomena

Sve funkcije za rotaciju primaju ugao izražen u radijanima. Kao i u prethodnim lekcijama, možemo koristiti konstantu PI.

Primer 1 – Rotacija kocke oko Y ose

// Ugao rotacije kocke
float ugao = 0;

void setup() {
    // Kreiranje prozora dimenzija 800x600 piksela.
    // Treći parametar P3D uključuje trodimenzionalni renderer.
    size(800, 600, P3D);
}

void draw() {
    // Boja pozadine (svetlosiva)
    background(220);

    // Pomeranje koordinatnog sistema u centar prozora.
    // Da ovo ne uradimo, kocka bi bila nacrtana u gornjem levom uglu.
    translate(width / 2, height / 2);

    // Rotacija kocke oko Y ose.
    // Ugao je izražen u radijanima.
    rotateY(ugao);

    // Crtanje kocke čija je stranica 150 piksela.
    box(150);

    // Povećavanje ugla rotacije.
    // Pošto se funkcija draw() izvršava više puta u sekundi,
    // kocka će izgledati kao da se neprekidno okreće.
    ugao += 0.02;
}

U ovom primeru kocka se okreće oko Y ose. Promenljiva ugao čuva trenutni ugao rotacije i u svakom prolazu kroz funkciju draw() povećava se za malu vrednost. Pošto se ekran osvežava više desetina puta u sekundi, posmatrač stiče utisak kontinuiranog okretanja kocke.

U svakom prolazu kroz funkciju draw() ugao se malo povećava, pa se kocka neprekidno okreće oko Y ose.

Eksperiment
  • Promenite brzinu rotacije.
  • Umesto rotateY() koristite rotateX().
  • Probajte funkciju rotateZ().
Rotacija kocke oko Y ose

Rotacija oko Y ose

Objekat se okreće oko vertikalne ose.

Rotacija oko X ose

rotateX()

Rotacija oko horizontalne ose.

Rotacija oko Z ose

rotateZ()

Rotacija u ravni ekrana.

Crtanje sfere

Pored kocke, Processing omogućava crtanje sfere pomoću funkcije sphere().

void setup() {
    size(800, 600, P3D);
}

void draw() {
    background(220);

    translate(width / 2, height / 2);

    sphere(90);
}

Argument funkcije predstavlja poluprečnik sfere.

Važno!

Ako ne uključite osvetljenje, sfera može izgledati potpuno ravno. Zbog toga se u 3D grafici veoma često koristi funkcija lights().

Dodavanje osvetljenja

Za razliku od 2D grafike, u trodimenzionalnim scenama veoma je važno odrediti način osvetljavanja objekata. Najjednostavniji način jeste korišćenje funkcije:

lights();

Ona uključuje podrazumevano osvetljenje i omogućava da se mnogo jasnije vide ivice i zakrivljene površine objekata.

void draw() {
    background(220);

    lights();

    translate(width / 2, height / 2);

    rotateY(frameCount * 0.02);

    sphere(90);
}
Probajte sami
  • Obrišite funkciju lights().
  • Posmatrajte kako izgleda sfera.
  • Zatim ponovo uključite osvetljenje.
3D sfera

Funkcija sphere()

Sfera predstavlja jedan od osnovnih 3D objekata u Processing-u.

Sfera bez osvetljenja

Bez osvetljenja

Objekat izgleda ravnije i manje uočljivo.

Sfera sa osvetljenjem

Sa osvetljenjem

Svetlo naglašava oblik i dubinu objekta.

Šta smo naučili?
  • kako se rotiraju 3D objekti,
  • razliku između funkcija rotateX(), rotateY() i rotateZ(),
  • kako se crta sfera,
  • zašto je funkcija lights() važna u 3D grafici.

U poslednjem delu lekcije naučićemo kako da u istoj sceni nacrtamo više objekata korišćenjem funkcija pushMatrix() i popMatrix(). Te funkcije predstavljaju osnovu za izradu složenijih 3D scena i biće veoma važne u narednim lekcijama kada budemo pravili Sunčev sistem i druge trodimenzionalne simulacije.

Više 3D objekata u istoj sceni

Do sada smo crtali jedan objekat u centru ekrana. U realnim 3D scenama često imamo više objekata koji se nalaze na različitim pozicijama i imaju različite rotacije.

Da bismo to postigli, moramo pravilno da upravljamo transformacijama.

Problem: zašto se sve rotira zajedno?

Pogledajmo sledeći primer:

translate(width / 2, height / 2);

rotateY(fi);

box(100);

translate(200, 0, 0);

box(50);

Na prvi pogled očekujemo da drugi objekat bude odvojen, ali on se i dalje ponaša kao deo iste transformacije.

Problem:

Sve transformacije se “lepe” jedna na drugu. Zbog toga je potrebno da koristimo zaštitu transformacija.

Rešenje: pushMatrix() i popMatrix()

Funkcije pushMatrix() i popMatrix() omogućavaju da sačuvamo i vratimo stanje koordinatnog sistema.

  • pushMatrix() – čuva trenutno stanje
  • popMatrix() – vraća prethodno stanje

Primer pravilnog crtanja više objekata

void draw() {
    // Boja pozadine prozora.
    background(220);

    // Pomeranje koordinatnog sistema u centar prozora.
    // Na taj način će se objekti crtati oko centra ekrana.
    translate(width / 2, height / 2);

    // Rotacija koordinatnog sistema oko Y ose.
    // Svi objekti nacrtani nakon ove naredbe biće rotirani.
    rotateY(fi);

    // ==================================================
    // Prvi objekat - kocka
    // ==================================================

    // Čuvamo trenutno stanje koordinatnog sistema.
    pushMatrix();

    // Crtanje kocke stranice 120 piksela.
    // Pošto nismo menjali položaj koordinatnog sistema,
    // kocka će biti nacrtana u centru scene.
    box(120);

    // Vraćamo prethodno stanje koordinatnog sistema.
    popMatrix();

    // ==================================================
    // Drugi objekat - sfera
    // ==================================================

    // Ponovo čuvamo stanje koordinatnog sistema.
    pushMatrix();

    // Pomeramo koordinatni sistem za 200 piksela po X osi.
    // Time određujemo položaj sfere u odnosu na kocku.
    translate(200, 0, 0);

    // Rotacija sfere oko X ose.
    rotateX(fi);

    // Crtanje sfere poluprečnika 60 piksela.
    sphere(60);

    // Vraćamo koordinatni sistem na stanje pre pomeranja.
    // Sledeći objekti neće biti pogođeni ovim transformacijama.
    popMatrix();

    // Povećavanje ugla rotacije.
    // U svakom prolazu kroz draw() objekti će se
    // nalaziti u novom položaju.
    fi += 0.02;
}

Svaki objekat sada ima svoj “lokalni prostor” i ne utiče na druge.

Mini projekat – 3D scena sa više objekata

U sledećem primeru kreiramo jednostavnu 3D scenu koja se sastoji od:

  • rotirajuće kocke u centru
  • sferе koja kruži oko nje
  • male pomoćne ose prostora
// Ugao koji određuje rotaciju objekata
float fi = 0;

void setup() {
    // Kreiranje prozora dimenzija 800x600 piksela.
    // Parametar P3D uključuje trodimenzionalni renderer.
    size(800, 600, P3D);
}

void draw() {
    // Tamna pozadina bolje ističe 3D objekte.
    background(30);

    // Uključivanje podrazumevanog osvetljenja scene.
    // Bez osvetljenja objekti mogu izgledati ravno.
    lights();

    // Pomeranje koordinatnog sistema u centar prozora.
    translate(width / 2, height / 2);

    // ==================================================
    // Crtanje koordinatnih osa
    // ==================================================

    // X osa (crvena)
    stroke(255, 0, 0);
    line(0, 0, 0, 200, 0, 0);

    // Y osa (zelena)
    stroke(0, 255, 0);
    line(0, 0, 0, 0, 200, 0);

    // Z osa (plava)
    stroke(0, 0, 255);
    line(0, 0, 0, 0, 0, 200);

    // Isključujemo crtanje ivica objekata.
    noStroke();

    // ==================================================
    // Centralna rotirajuća kocka
    // ==================================================

    // Čuvamo trenutno stanje koordinatnog sistema.
    pushMatrix();

    // Rotacija kocke oko Y ose.
    rotateY(fi);

    // Boja kocke.
    fill(200, 100, 255);

    // Crtanje kocke.
    box(120);

    // Vraćamo prethodno stanje koordinatnog sistema.
    // Sve transformacije izvršene između pushMatrix()
    // i popMatrix() važe samo za ovu kocku.
    popMatrix();

    // ==================================================
    // Sfera koja kruži oko kocke
    // ==================================================

    // Ponovo čuvamo stanje koordinatnog sistema.
    pushMatrix();

    // Rotiramo koordinatni sistem oko Y ose.
    rotateY(fi);

    // Pomeramo koordinatni sistem za 200 piksela po X osi.
    // Pošto je koordinatni sistem već rotiran,
    // sfera će kružiti oko centralne kocke.
    translate(200, 0, 0);

    // Boja sfere.
    fill(255, 200, 0);

    // Crtanje sfere poluprečnika 40 piksela.
    sphere(40);

    // Vraćamo koordinatni sistem na prethodno stanje.
    popMatrix();

    // Povećavanje ugla rotacije.
    // Time se u sledećem prolazu kroz draw()
    // objekti nalaze u novom položaju.
    fi += 0.02;
}
3D scena sa više objekata

Više objekata

Svaki objekat ima svoju transformaciju i poziciju u prostoru.

3D ose prostora

Ose prostora

X, Y i Z ose pomažu u orijentaciji u 3D prostoru.

Objekat koji kruži

Orbitalno kretanje

Objekti mogu da se kreću oko drugih objekata.

Mini kviz

Pitanja:
  • 1. Čemu služi P3D u Processing-u?
  • 2. Koja funkcija omogućava kretanje objekta u prostoru?
  • 3. Koja funkcija sprečava da se transformacije “mešaju”?
  • 4. Koja osa predstavlja dubinu prostora?

Zadaci za samostalan rad

  • Dodaj još jedan objekat koji kruži oko centra.
  • Promeni boje svih objekata u sceni.
  • Povećaj radijus orbite sferе.
  • Dodaj treću rotirajuću kocku.

Šta dalje?

U sledećoj lekciji prelazimo na veoma važan koncept:

  • kamera u 3D prostoru (camera())
  • perspektiva (perspective())
  • kontrola pogleda u sceni

Zatim ćemo primeniti sve što smo naučili i napraviti: Sunčev sistem u 3D-u

Završna napomena

Ako razumete kako rade transformacije u ovoj lekciji, već ste savladali 80% osnova 3D grafike u Processing-u.

Proveri znanje

Otvori kviz

Kviz: Prvi koraci u 3D

1. Kako se uključuje 3D režim?




2. Šta crta box(100)?




3. U kom smeru ide z osa u Processing-u?




4. Čemu služi lights()?