Modul 5
Modul 5
Untuk implementasi sistem koordinat bidang 3D di p5.js, kita gunakan mode WEBGL di
fungsi createCanvas() di dalam fungsi setup(). Misalkan jendela aplikasi berukuran 800
x 600, maka kita tuliskan: createCanvas(800,600,WEBGL). Dengan itu kita sudah memiliki
akses ke sumbu Z dan bisa menggunakan fungsi-fungsi yang menggunakan koordinat Z
sebagai parameternya.
Selanjutnya kita akan mulai memakai Bentuk Primitif dalam bidang 3D.
Di p5.js, cara kerja dari primitif 3D berbeda dengan primitif 2D. Jika di bidang 2D kita bisa
menentukan koordinat x,y, dan ukuran dari bentuk yang ada, di bidang 3D kita hanya bisa
menentukan ukurannya. Bentuk primitif 3D di p5.js selalu dibentuk di koordinat (0,0,0)
yang berada di tengah-tengah canvas. Sehingga jika canvas berukuran 800 x 400, maka
koordinat (0,0,0) berada seakan-akan di titik (400,200). Sehingga jika ingin menggeser
letaknya, kita harus menggunakan fungsi translate().
[ 73 ]
Selain itu bentuk 3D juga dipengaruhi oleh stroke() untuk warna garis mesh dari bentuk,
dan fungsi fill() untuk warna dari permukaan bentuk 3D. Sehingga dimungkinkan juga
untuk membuat bentuk 3D tanpa garis mesh dengan menggunakan noStroke(), atau pun
tanpa warna permukaan dengan menggunakan noFill().
Balok (Box)
Untuk balok kita gunakan fungsi box() dengan dua cara pemakaian:
box(p, t, l) / box(ukuran)
function draw(){
background(255);
lights();
strokeWeight(3);
fill(255,0,0);
push();
stroke(0);
translate(-150,0);
box(200);//balok dengan garis dan warna
pop();
push();
noFill();
translate(150,-100);
box(200,100,100);//balok dengan garis saja
pop();
push();
fill(255,0,0);
noStroke();
translate(150,100);
box(200,100,100);//balok dengan warna saja
pop();
}
[ 74 ]
Bola (Sphere)
Untuk membentuk bola, fungsi sphere berisi tiga parameter yaitu ukuran, detail x dan
detail y. Paramater detail boleh dipakai atau tidak (optional), sehingga pemakaian fungsi
bola biasanya adalah: sphere(ukuran).
Contoh penerapannya adalah sebagai berikut:
function setup(){
createCanvas(600,600,WEBGL);
background(255);
}
function draw(){
background(255);
lights();
sphere(200);
}
Untuk bentuk bola ini terdapat parameter detailX dan detailY untuk menyetel jumlah
dan detail dari polygonal mesh bola yang dibentuk dengan nilai default maksimal yang
disarankan adalah 24. Lebih dari itu akan menyebabkan warning atau aplikasi melambat.
Kegunaan dari fungsi tersebut adalah untuk menyetel detail dari bola. Semakin tinggi detail
maka semakin halus bentuk bola yang ditampilkan. Tapi jika perlu memunculkan bola
dalam jumlah besar (misalkan 100), maka detail bola sebaiknya diturunkan agar tidak
memberatkan sistem.
Di samping adalah contoh
bentuk bola dengan nilai
kombinasi nilai detail x dan y
dari 1 s.d 4.
Bisa dilihat bahwa dengan
mengatur detail, kita bisa
mendapatkan bentuk
polihedral seperti bentuk
oktahedron dengan detail x =
3, dan y = 2, atau tetragonal
bipyramid dengan detail x = 4,
dan y = 2. Semakin tinggi nilai
detail x dan y, maka semakin
terbentuk bola yang halus.
[ 75 ]
Bidang (Plane)
Bentuk bidang adalah bidang datar persegi empat yang bisa diatur panjang dan lebarnya
dengan fungsi plane(panjang, lebar). Bentuk ini biasa digunakan untuk membentuk
lantai, dinding, atau batasan dalam lingkungan 3D.
Contoh penerapannya dengan diputar pada sumbu X sebesar 60 derajat:
function setup(){
createCanvas(500,500,WEBGL);
background(255);
}
function draw(){
background(255);
lights();
rotateX(radians(60));
plane(300,300);
}
Silinder (Cylinder)
Bentuk silinder atau tabung adalah bentuk yang memiliki tutup dan alas berupa lingkaran
yang dikelilingi bidang datar. Di p5.js, fungsi silinder memiliki dua parameter utama: lebar
jari-jari lingkaran dan tinggi silinder, dan dua parameter tambahan yaitu detail x dan y
seperti pada lingkaran. Fungsi silinder yang dipakai adalah cylinder(jari-jari,
tinggi).
Contoh penerapan yang diputer pada sumbu X sebesar -40 derajat dan detail x = 22 dan y
= 2 (default 1)
function setup(){
createCanvas(500,500,WEBGL);
background(255);
}
function draw(){
background(255);
lights();
rotateX(radians(-40));
cylinder(100,300,22,1);
}
Kerucut (Cone)
Bentuk kerucut pada dasarnya seperti piramid namun dengan alas berbentuk lingkaran.
Sama seperti bentuk silinder, fungsi kerucut memiliki dua parameter utama: jari-jari dan
tinggi kerucut, serta dua parameter tambahan: detail x dan detail y. Pemakaian fungsi
[ 76 ]
kerucut adalah dengan cone(jari-jari, tinggi) dengan kerucut yang dihasilkan
posisinya terbalik.
Contoh penerapan kerucut yang diputer di sumbu x sebesar -40 derajat
function setup(){
createCanvas(500,500,WEBGL);
background(255);
}
function draw(){
background(255);
lights();
rotateX(radians(-40));
cone(100,400);
}
Elipsoid (Ellipsoid)
Elipsoid adalah bentuk ellipse tapi dalam 3D – artinya bentuk bola (sphere) yang panjang,
lebar, dan tingginya (dalam bentuk jari-jari) bisa diatur. Sehingga terdapat tiga parameter
utama: jari-jari di sumbu x, jari-jari di sumbu y, dan jari-jari di sumbu z. Selain itu terdapat
dua parameter tambahan seperti pada bentuk bola: detail x dan y – sehingga
pemanfaatannya sama.
Contoh elipsoid untuk mendapatkan bentuk “telur”
function setup(){
createCanvas(500,500,WEBGL);
background(255);
}
function draw(){
background(255);
lights();
ellipsoid(150,200,200);
}
Torus
Bentuk torus jika mau dikatakan dengan nama lain adalah “donat”. Pada dasarnya torus
adalah lingkaran tertutup yang melingkar (tube) di bidang 3D sehingga membentuk cincin.
Dalam p5.js, fungsi torus memiliki dua parameter utama: jari-jari dan jari-jari tube, dan juga
dua parameter tambahan: detail x dan detail y dengan nilai default masing-masing adalah
24 dan 16.
[ 77 ]
Untuk pemakaian fungsi torus secara mendasar adalah torus(jari-jari torus, besar jari-jari
tube).
Berikut adalah contoh penerapannya
function setup(){
createCanvas(500,500,WEBGL);
background(255);
}
function draw(){
background(255);
lights();
rotateX(radians(40));
torus(150,50);
}
Dengan mengganti nilai detail, bentuk torus bisa diatur dan bahkan bisa mem bentuk donat
segitiga seperti berikut:
function draw(){
background(255);
lights();
rotateX(radians(40));
torus(150, 50, 3, 16);
}
Pemrograman Bentuk 3D
Di p5.js kita juga melakukan pemrograman
bentuk 3D dengan menggunakan fungsi
beginShape(), vertex(), dan endShape().
[ 78 ]
bentuk tersebut dan sistem koordinat yang dipakai adalah sistem koordinat p5.js dengan
sumbu y positif mengarah ke bawah.
Nilai 1 satu tersebut bisa diganti dengan nilai yang lebih besar untuk membentuk
octahedron.
Untuk implementasi pembentukan octahedron di p5.js, kita bisa melakukan sebagai
berikut dengan nilai “1” di anatomi di ganti menjadi variabel “a”:
let a = 0; vertex(0,a,0);
function setup(){ vertex(-a,0,0);
createCanvas(600,600,WEBGL);
background(255); vertex(0,0,a);
a = 225; vertex(0,-a,0);
} vertex(-a,0,0);
[ 79 ]
Selain vertex, penyesuaian dari anatomi yaitu variabel “a” sebagai pengganti nilai “1” untuk
koordinat disetel sebesar 225 sebagai ukuran dari octahedron, kemudian dipakai sebagai
nilai dalam vertex() pembentuk octahedron di antara beginShape() dan endShape().
Seperti dalam bidang 2D, kita juga bisa membuat pemrograman bentuk sebagai fungsi agar
bisa langsung dipakai ketika dibutuhkan. Misalkan untuk membuat octahedron sebagai
fungsi, kita bisa melakukan implementasi sebagai berikut
function oktahedron(a){ vertex(0,0,-a);
beginShape(); vertex(0,-a,0);
vertex(0,0,a); vertex(-a,0,0);
vertex(0,-a,0);
vertex(a,0,0); vertex(0,0,-a);
vertex(0,a,0);
vertex(0,0,a); vertex(-a,0,0);
vertex(0,a,0);
vertex(a,0,0); vertex(0,0,-a);
vertex(0,a,0);
vertex(0,0,a); vertex(a,0,0);
vertex(0,a,0);
vertex(-a,0,0); vertex(0,0,-a);
vertex(0,-a,0);
vertex(0,0,a); vertex(a,0,0);
vertex(0,-a,0); endShape(CLOSE);
vertex(-a,0,0); }
Pemakaian fungsi tersebut dengan contoh sama seperti sebelumnya dengan membuat
dua bentuk oktahedron:
function setup(){ … }
function draw(){
background(255);
lights();
fill(255);
strokeWeight(3);
push();
translate(-150,-100,0);
rotateY(millis()*0.001*radians(15));
oktahedron(150);
pop();
push ();
translate(150,100,0);
rotateY(millis()*0.001*radians(15));
oktahedron(150);
pop ();
}
Kode program di atas membuat dua oktahedron berukuran 150 yang berputar 15 derajat
ke kanan per detiknya; yang satu di koordinat (-150,-100,0) dan yang ke-2 di koordinat
(150,100,0). Dengan fungsi kita tidak perlu menuliskan ulang pembentukan sisi poligon
dari bentuk 3D. Untuk memakainya secara berulang kita tetap harus menuliskan
[ 80 ]
transformasi geometri translate() untuk menentukan koordinat pembentukannya, dan
tentu saja fungsi push() dan pop() agar transformasi bisa dibatasi pada satu bentuk.
Dalam bidang 3D sendiri juga terdapat transformasi geometri yang bisa dipakai.
Translasi Bidang 3D
Untuk translasi di bidang 3D, sudah ditunjukkan dalam contoh-contoh sebelumnya bahwa
fungsi translate() digunakan untuk menentukan letak dari pembentukan bangun ruang
(bentuk 3D). Terdapat nilai x, y, dan z yang harus ditentukan. Untuk x dan y seperti pada
bidang 2D; sedangkan untuk z, nilai positif berarti membuat benda semakin dekat ke arah
kita, dan nilai negative membuat benda semakin menjauh dari kita. Misalkan dari contoh
dua oktahedron sebelumnya, namun dengan diubah nilai z nya di translate() sebagai
berikut.
…
function draw(){
…
push();
translate(-150,-100,-150);
…
oktahedron(150);
pop();
push();
translate(150,100 ,150);
…
oktahedron(150);
pop();
}
Nilai koordinat z dari kedua oktahedron tersebut yang kiri -150 yang berarti menjauh dari
kita, dan yang kanan 150 yang berarti mendekat ke arah kita. Berikutnya adalah
transformasi rotasi dalam bidang 3D.
Rotasi Bidang 3D
Rotasi di bidang 3D bisa dibagi menjadi tiga sesuai
sumbu koordinat: rotasi terhadap sumbu x, rotasi
terhadap sumbu y, dan rotasi terhadap sumbu z. Di
samping adalah gambaran dari masing-masing rotasi
terhadap sumbu koordinat x, y, dan z dalam bidang
3D.
[ 81 ]
Bisa dilihat bahwa di p5.js, arah rotasi dalam bidang 2D sama dengan rotasi terhadap
sumbu z (rotateZ()) di bidang 3D. Dengan arah searah atau melawan putaran jarum jam.
Kemudian untuk rotasi terhadap sumbu y (rotateY()) adalah perputaran ke arah kanan
atau kiri benda. Contoh arah rotasi terhadap sumbu y adalah rotasi planet. Untuk rotasi
terhadap sumbu x (rotateX()) adalah perputaran ke arah depan atau belakang. Contoh
arah rotasi terhadap sumbu x adalah rotasi monitor laptop yang dibuka atau di tutup.
Seperti dalam bidang 2D, rotasi dalam bidang 3D juga bisa dianimasikan dengan
memanfaatkan fungsi millis(). Sehingga seperti dalam 2D, rotasi 3D juga bisa diatur
sampai sekian derajat per detik untuk animasinya. Berikut adalah contoh pemanfaatan
rotasi dalam bidang 3D dengan animasinya menggunakan fungsi oktahedron yang dibuat
sebelumnya:
function setup(){…}
function draw(){
background(255);
lights();
fill(255);
strokeWeight(3);
push();
translate(-150,-150,0);
rotateX(millis()*0.001*radians(15));
oktahedron(120);
pop();
push();
translate(0, 0, 0);
rotateY(millis()*0.001*radians(15));
oktahedron(120);
pop();
push();
translate(150,150,0);
rotateZ(millis()*0.001*radians(15));
oktahedron(120);
pop();
}
function oktahedron(float a){…}
Secara berurutan dari kiri-atas ke kanan-bawah adalah oktahedron berukuran 120 yang
dirotasi sebanyak 15 derajat per detik terhadap sumbu x, y, dan z. Untuk mempercepat
putaran kita bisa menambah nilai dari sudut rotasi, dan untuk mengubah arah rotasi kita
menggunakan nilai negatif (misal: -15). Transformasi selanjutnya adalah skala dalam bidang
3D.
Skala Bidang 3D
Transformasi skala dalam bidang 3D bekerja seperti dalam bidang 2D: membesarkan
bentuk berdasarkan scale factor dengan acuan pembesaran di koordinat (0,0,0). Bedanya
[ 82 ]
adalah di bidang 3D bentuk selalu dibuat di koordinat (0,0,0) dengan melakukan translasi
ke titik tertentu; sehingga skala yang dilakukan selalu otomatis membesarkan langsung
bentuk 3D yang ada.
Contoh penggunaan skala dari contoh sebelumnya, oktahedron yang mengalami rotasi
terhadap sumbu y dibersarkan 2 kali:
void setup(){…}
void draw(){
…
pushMatrix();
translate(300,300,0);
scale(2.0);
rotateY(millis()*0.001*radians(15));
oktahedron(120);
popMatrix();
…
}
void oktahedron(float a){…}
Yang perlu diingat bahwa fungsi skala dalam bidang 3D juga membesarkan ukuran dari
strokeWeight() dari bentuk 3D. Sehingga oktahedron yang diskalakan di atas memiliki
ukuran stroke menjadi 6 karena sebelumnya sudah berukuran 3.
Selain skala, transformasi geometri shear juga bisa diterapkan pada bidang 3D yang bisa
menyebabkan bentuk 3D menjadi condong berdasarkan sumbu koordinat. Hanya saja
karena di p5.js fungsi shear hanya ada dua: shearX() dan shearY(), sehingga masih
terbatas untuk bidang 3D secara utuh.
Selanjutnya kita akan membahas bagaimana membuat bentuk 3D yang “realistis” yaitu
dengan tekstur, pengaturan cahaya, dan kamera.
Tekstur Bentuk 3D
Tekstur pada dasarnya adalah “kulit” dari sebuah benda. Tekstur di bentuk 3D yang bisa
menentukan apakah sebuah bentuk 3D bisa terlihat “realistis” atau tidak. Agar lebih
realistis biasanya pemanfaatan tekstur juga digabung dengan implementasi shaders dan
pengaturan cahaya dalam bidang 3D.
Di p5.js, untuk melakukan implementasi tekstur harus membuat sebuah objek p5.Image
terlebih dahulu, kemudian mengaplikasikan objek tersebut sebagai tekstur dengan:
1) Memetakan tekstur ke setiap sisi objek 3D
2) Menentukan tekstur sebuah objek 3D
Untuk cara pertama, dipakai ketika kita butuh memetakan tekstur ke bentuk yang
berukuran tidak sama lebar, panjang, atau tingginya (misal: balok), atau bentuk lain seperti
[ 83 ]
oktahedron, piramida, dll. Cara ini juga bisa digunakan untuk bentuk yang lebih sederhana
seperti kubus.
Untuk implementasi tekstur, kita siapkan dulu file tekstur yang dibutuhkan. Misalkan kita
ingin membuat sebuah objek kotak kayu yang memanfaatkan bentuk kubus dan tekstur
kotak kayu. Kita bisa mencari tekstur kotak kayu di mesin
pencari seperti google dll.
Tekstur disamping diambil dari situs OpenGameArt.org
(https://opengameart.org/content/3-crate-textures-w-
bump-normal) dengan nama file telah diubah ke
“tekstur-kayu-1.png” yang berukuran 512x512 px,
dan akan kita gunakan sebagai tekstur ke kubus
berukuran 200.
Untuk cara pertama, implementasinya sebagai berikut:
vertex(-100, -100, -100, 1, 0);
let teksturKotak; vertex(-100, 100, -100, 1, 1);
vertex( 100, 100, -100, 0, 1);
function preload(){ endShape(CLOSE);
teksturKotak =
loadImage('tekstur-kayu-1.png'); beginShape();//sisi "alas" Y+
} vertex(-100, 100, 100, 0, 0);
vertex( 100, 100, 100, 1, 0);
function setup(){ vertex( 100, 100, -100, 1, 1);
createCanvas(600,600,WEBGL); vertex(-100, 100, -100, 0, 1);
background(255); endShape(CLOSE);
teksturKotak.resize(200,200);
} beginShape();//sisi "alas" Y+
vertex(-100, -100, -100, 0, 0);
function draw(){ vertex( 100, -100, -100, 1, 0);
background(255); vertex( 100, -100, 100, 1, 1);
lights(); vertex(-100, -100, 100, 0, 1);
translate(0,150,0); endShape(CLOSE);
rotateY(millis()*0.001*
radians(30)); beginShape();//sisi "kanan" X+
vertex( 100, -100, 100, 0, 0);
textureMode(NORMAL); vertex( 100, -100, -100, 1, 0);
texture( teksturKotak ); vertex( 100, 100, -100, 1, 1);
vertex( 100, 100, 100, 0, 1);
beginShape();//sisi "depan" Z+ endShape(CLOSE);
vertex(-100, -100, 100, 0, 0);
vertex( 100, -100, 100, 1, 0); beginShape();//sisi "kiri" X-
vertex( 100, 100, 100, 1, 1); vertex(-100, -100, -100, 0, 0);
vertex(-100, 100, 100, 0, 1); vertex(-100, -100, 100, 1, 0);
endShape(CLOSE); vertex(-100, 100, 100, 1, 1);
vertex(-100, 100, -100, 0, 1);
beginShape();//sisi "belakang" Z- endShape(CLOSE);
vertex( 100, -100, -100, 0, 0); }
Kode di atas mengimplementasikan tekstur ke setiap sisi kubus. Bagian teks yang
ditebalkan menunjukkan penerapan tekstur pada bentuk kubus yang dibuat. Dimulai dari
[ 84 ]
memuat, mengatur ukuran ke 200 x 200, hingga
diterapkan dengan fungsi texture(). Hasilnya
seperti yang terlihat di samping.
[ 85 ]
let teksturKotak;
function preload(){
teksturKotak = loadImage('tekstur-kayu-1.png');
}
function setup(){
createCanvas(600,600,WEBGL);
background(255);
teksturKotak.resize(200,200);
}
function draw(){
background(255);
lights();
translate(0,150,0);
rotateY(millis()*0.001*radians(30));
texture( teksturKotak );
box(200);
}
Untuk bentuk yang sederhana dengan primitif 3D, kita bisa lebih cepat dengan cara ke-2
ini. Hanya perlu menentukan tekstur yang ingin dipakai, kemudian tampilkan bentuk yang
ingin diberi tekstur tersebut (seperti pemanfaatan fungsi fill() terkait warna objek)
function preload(){
teksturBumi = loadImage('tekstur-bumi.jpg');
}
function setup(){
createCanvas(600,600,WEBGL);
background(255);
}
function draw(){
background(255);
lights();
translate(0,0,0);
[ 86 ]
rotateY(millis()*0.001*radians(30));
texture( teksturBumi );
noStroke();
sphere(200);
}
Untuk implementasi tekstur ke bentuk bola, kita tidak perlu melakukan resize() ke
tekstur yang digunakan karena akan secara otomatis diatur oleh p5. Juga perlu
diperhatikan bahwa terdapat noStroke() sebelum menampilkan bola yang diberi tekstur.
Tujuannya agar bentuk bumi yang ditampilkan tidak menampilkan garis rangka bola,
sehingga bisa menampilkan “bumi” dengan benar.
[ 87 ]
x, y, dan z, parameter arah cahaya berdasarkan koordinat x, y, dan z, sudut
penyebaran cahaya, dan konsentrasi cahaya .
Selain empat jenis itu, terdapat fungsi default untuk pencahayaan di p5.js yaitu lights()
yang menjalankan fungsi ambientLight() dan directionalLight() secara default, dan juga
fungsi lightFalloff() –efek cahaya yang lebih gelap ke benda yang miring, dan
lightSpecular() –yaitu mengatur bagaimana cahaya memantul dari benda.
• eyeX, eyeY, eyeZ – adalah koordinat dari “mata” / posisi kamera di bidang 3D
• centerX, centerY, centerZ – adalah koordinat kemana kamera memandang
• upX, upY, upZ – arah atas dari kamera. Biasanya bernilai (0,1,0) dengan sumbu Y
ke atas
Fungsi camera() bisa dipakai secara default tanpa parameter yang akan menyetel
parameternya dengan nilai berikut:
• eyeX (width/2.0), eyeY(height/2.0), eyeZ ( (height/2.0) / tan(PI*30.0
/ 180.0) )
• centerX (width/2.0), centerY (height/2.0), centerZ (0)
• upX (0), upY (1), upZ (0)
[ 88 ]
Dengan menyetel parameter fungsi camera() ini, kita bisa mengatur dari mana kita
memandang objek yang kita bentuk. Misalkan dengan berdasar contoh sebelumnya, kita
bisa mengatur implementasi kamera sebagai berikut:
function setup(){… }
...
function draw(){
background(0);
lights();
camera(0, -300, 500,
0, 0, 0,
0, 1, 0);
translate(0,0,0);
rotateY(millis()*0.001*radians(30));
texture( teksturBumi );
noStroke();
sphere(200);
}
[ 89 ]
TUGAS PRAKTIKUM MODUL 5 – APLIKASI GRAFIK 3D
Buatlah aplikasi grafik 3D yang menampilkan matahari, bumi, dan bulan. Dapatkan tekstur
matahari, bumi, dan bulan dari http://planetpixelemporium.com/planets.html dan
gunakan sebagai tekstur di p5.js. Tampilkan ketiganya dengan posisi matahari berada di
tengah, bumi mengitari matahari, dan bulan juga mengitari bumi. Terdapat cahaya yang
terpancar dari matahari ke segala arah.
Ketentuan aplikasi:
✓ Buat jendela aplikasi berukuran 1000x720
✓ Buat kamera memandang dari agak atas sehingga terlihat matahari, bumi, dan
bulannya yang saling mengitari (buat koordinat kamera di X: 0, Y: -500, Z: 700 dan
memandang ke arah matahari)
✓ Setel ukuran matahari: 300, bumi: 100, bulan: 30
✓ Kecepatan per detik: rotasi matahari -10°, revolusi bumi 30°, revolusi bulan 90°
✓ Gunakan pointLight() untuk cahaya yang berasal dari matahari
[ 90 ]