2017年12月17日 星期日

楊喻文的學習手札 20171214

week14

Rasterization

張鈞法老師網站(計算機圖學)
http://cg.csie.ntnu.edu.tw/CG/



Rasterization (光柵化)

把一張3D的圖壓扁成2D
畫很多格子(pixel),每個格子填上顏色
主要使用fragment shader



課程實作1:
<用processing語言>畫出三角形

//OPENGL寫法
size(600,600,P3D);
background(255);
//glBegin(GL_POLYGON);
beginShape(TRIANGLE);
    //glColor3f(r,g,b);
    //glVertexsf(x,y,z);
    stroke(255,0,0);vertex(300,100);
    stroke(255,255,0);vertex(500,500);
    stroke(0,0,255);vertex(100,500);
//glEnd()
endShape();
 

把stroke改成fill就可以讓三角形裡面塗滿顏色



*為什麼要畫三角形?
    因為任何多邊形都可以用三角形解決,所以硬體實作時只要專注在把三角形畫好就好,讓速度變快三角形畫好了,其他多邊形就不是問題了
    但是繪畫出凸三多邊形還是凹多邊形會是一個問題,凹多邊形常常會看不出來,長的就跟平面依樣
(疑似凸多邊形)
    畫人臉的時候常會用四邊形去畫,因為用三角形的畫人臉會太破,但是為了要求速度,很多遊戲還是會用三角形去處理

glutInitDisplayMode(GLUT_DOUBLE || GLUT_DEPTH)
有深度值才有Z值,有Z值才有3D

課程實作2:
<用processing語言>畫出重疊三角形

void setup(){
  size(600, 600, P3D);
}
void draw(){
 background(255);
 //first triangle
 beginShape(TRIANGLE);
  fill(255,0,0); vertex(100,100,0);
  fill(255,0,255); vertex(100,500,100);
  fill(255,255,0); vertex(500,500,0);
 endShape();
 //second triangle
 beginShape(TRIANGLE);
  fill(0,255,0); vertex(500,100,0);
  fill(0,255,255); vertex(500,500,100);
  fill(255,255,0); vertex(100,500,0);
 endShape();
}


先看如果只有畫第一個三角形的或會長甚麼樣子


如果調整上面程式碼藍色的值(例如改成20)
可以看到三角形就會變得不一樣


不同深度(不同z值),決定顏色要畫甚麼顏色
三角形中每一個頂點都有自己的Z值 (所有東西包含顏色、位置值、深度值都有內插)

兩個三角形中間的交界(鋸齒狀部分),要怎麼知道歸甚麼顏色?
   他會去計算Z值,內插的時候,比較接近使用者的就會被顯示出來

<期末作品示範1> 3D MARIO
與其全部想好還是不知道怎麼下手
不如邊寫邊想

但是我現在查到的資料都看不是很懂要怎麼辦QAQ

void setup(){
  size(600, 400, P3D);
}
//set position of mario at center
float marioX=300, marioY=300, marioZ=0;
//mario direction
int marioDir=0; //0:nothing, 1:right, 2:left, 3:up, 4:down
void draw(){
 background(#6DD5FA);//blue sky
 //ground
 beginShape(QUAD);//draw square
  vertex(0,300,-30);
  vertex(0,300,300);
  vertex(600,300,300);
  vertex(600,300,-300);
 endShape();

//mario position
 lights(); //lighting
 pushMatrix();
  translate(marioX, marioY, marioZ);
 noStroke();
  sphere(30); //if mario is a ball
 popMatrix();

//mario move by direction
if(marioDir==1) marioX+=3;
if(marioDir==2) marioX-=3;
if(marioDir==3) marioZ-=3;
if(marioDir==4) marioZ+=3;
}

//move mario ny keyboard
void keyPressed(){
 if(keyCode==RIGHT) marioDir=1;
 if(keyCode==LEFT) marioDir=2;
 if(keyCode==UP) marioDir=3;
 if(keyCode==DOWN) marioDir=4;
}

void keyReleased(){
 marioDir=0;
}

如果想要讓馬力歐可以跳的話可以再加空白鍵
然後呢讓馬力歐動得更滑順~

[第二版本]
void setup(){
  size(600, 400, P3D);
}
//set position of mario at center
float marioX=300, marioY=300, marioZ=0, marioVX=0, marioVY=0, marioVZ=0;

void draw(){
 background(#6DD5FA);//blue sky
 //ground
 beginShape(QUAD);//draw square
  vertex(0,300,-300);
  vertex(0,300,300);
  vertex(600,300,300);
  vertex(600,300,-300);
 endShape();

//mario position
 lights(); //lighting
 pushMatrix();
  translate(marioX, marioY, marioZ);
  noStroke();
  sphere(20); //if mario is a ball
 popMatrix();

 marioX+=marioVX;
 marioZ+=marioVZ;
 if(jumping){
   marioY+=marioVY;
   marioVY+=0.98;
   if(marioY>300) {jumping=false; marioVY=0; marioY=300;}
 }
}

//let mario jump
boolean jumping=false;

//move mario by keyboard
void keyPressed(){
 if(keyCode==RIGHT) marioVX=3;
 if(keyCode==LEFT) marioVX=-3;
 if(keyCode==UP) marioVZ=-3;
 if(keyCode==DOWN) marioVZ=3;
 if(keyCode==' ' && jumping==false) {marioVY=-20; jumping=true;}
}
void keyReleased(){
 if(keyCode==RIGHT || keyCode==LEFT) marioVX=0;
 if(keyCode==UP || keyCode==DOWN) marioVZ=0;

}

(跳起來=D)


<期末作品示範2> Google 程式兔子
有用打光、變顏色
directionallight(r,g,b, x,y,z);//rgb為顏色 xyz為打光方向

其他部分覺得速度有點快
來不及打









沒有留言:

張貼留言