這次作業要做動模糊(Motion Blur),自己有攝影的經驗,知道快門速度若比物體動作慢,就會產生此現象,可以區分動靜狀態,在藝術表達上很常被使用。而這次所需要的技巧不難,只要設定兩個參數:模糊程度和物體移動程度即可,接著依照模糊程度來持續繪圖,最後將累積的顏色平衡到畫一張圖的程度。
接著來看我所實驗的結果:
接著看我所實做的程式碼:
int red[WIDTH][HEIGHT]={}, green[WIDTH][HEIGHT]={}, blue[WIDTH][HEIGHT]={};
void Engine::Render(int number, int numbermax){
// render scene
vector3 eye(0, 0, -5);
ColorImage image;
Pixels pix={0, 0, 0};
image.init(WIDTH, HEIGHT);//初始化影像面積
// render remaining lines
for(int y = 0; y < HEIGHT; y++){
// render pixels for current line
for(int x = 0; x < WIDTH; x++){
// fire primary ray
vector3 dir=vector3((x-WIDTH/2)*0.02, -(y-HEIGHT/2)*0.02, -1*0.02)-eye;
NORMALIZE(dir);
Ray ray(eye, dir);//產生光線
Color acc(0, 0, 0);
float dist;
Raytrace(ray, acc, 1, 1.0f, dist);//開始ray tracing遞迴
red[x][y] += (int)(acc.r * 256);//[0,1] to [0,255]
green[x][y] += (int)(acc.g * 256);
blue[x][y] += (int)(acc.b * 256);
if(red[x][y] > 255*numbermax) red[x][y] = 255*numbermax;//控制顏色最大值[0,255*繪圖次數]
if(green[x][y] > 255*numbermax) green[x][y] = 255*numbermax;
if(blue[x][y] > 255*numbermax) blue[x][y] = 255*numbermax;
if(number==numbermax){//最後一次繪完圖
red[x][y] /= numbermax;//回歸顏色值介於[0,255]
green[x][y] /= numbermax;
blue[x][y] /= numbermax;
pix.R = red[x][y];//指定顏色給pixel結構
pix.G = green[x][y];
pix.B = blue[x][y];
image.writePixel(x, y, pix);//將每個pixel寫入影像
}
}
}
image.outputPPM("result.ppm");//輸出ppm影像
// all done
}
void Engine::Render(int number, int numbermax),參數number為第幾次繪圖,參數numbermax為繪圖次數,顏色每次繪圖都會累積,每次顏色累積[0,255],若累積4次,總共顏色累積[0,1020],在第4次繪圖結束後,將累積的顏色除以4,控制顏色介於[0,255]。
之所以會有實驗二顏色斷層,是因為我在每次繪圖完即做*0.25(/4)的動作,接著累積4次的結果就會產生明顯的斷層。舉例:A*0.25+B*0.25+C*0.25+D*0.25後來改進成(A+B+C+D)*0.25,斷層就消失了。這樣是有道理的,因為前者多做3次除法,除了會影響成像速度,還會遺失一些數據,於是就會有斷層的現象囉~
實驗結果呈現,繪圖次數越多,每次繪圖位移越小,即可產生像拍照那樣子的動模糊程度。然而隨著繪圖次數的增加,表示累積的繪圖時間也會隨著繪圖次數而線性增加。





隨意留個言吧:)~