3D Game Programming 2D primitive Ming-Te Chi Department of Computer Science, National Chengchi University 2018
Outline Imaging and Raster Primitives Alpha and Blending Intersection 2016
Imaging and Raster Primitives An Interactive Introduction to OpenGL Programming Imaging and Raster Primitives
Super Mario Bros. Nintendo Sprite Super Mario Bros. Nintendo
Electromagnetic spectrum http://en.wikipedia.org/wiki/Electromagnetic_spectrum 可見光是電磁波的子集,這張圖顯示各尺度波長的性質和特色 Image from wiki
Three-Color Theory Human visual system has two types of sensors Rods: monochromatic, night vision Cones: Color sensitive Three types of cone Only three values (the tristimulusvalues) are sent to the brain 人眼的視網模主要由兩種感光細胞所組成 柱狀細胞: 感受亮度的變化 錐狀細胞: 再區分為三大類,分別感應不同波段的可見光,也就是紅綠藍三色,這也就是為何人眼視覺以三原色為主
Additive / Subtractive color Y M C Subtractive Color Printer Additive Color LCD, projector 光的三原色由RGB(紅綠藍構成),也就是一次色,顯示器或投影機由光的三原色組成各種顏色。兩兩混色可形成二次色,剛好對應減色系統的一次色
RGB color space Green Black (0, 0, 0) Red Blue http://www.demilked.com/rgb-colorspace-atlas-every-color-imaginable/ Blue a 8 x 8 x 8-inch cube book Tauba Auerbach
Bitmap width height xorig yorig xmove
Raster Graphics Image produced as an array (the raster) of picture elements (pixels) in the frame buffer (179, 161, 153) 在此簡述一下,呈像的原理 一張影像可視為由二維的像素(pixel)所組成,而每個像素則是包含了RGB (紅綠藍)三色的強度 在電腦中有一塊特別的記憶體稱之為framebuffer,它記錄了這些像素的資訊,並與顯示器的發光體有著一對一的對應 因此改變framebuffer內部的值,顯示器的畫面也隨之改變, 所以在設計遊戲的畫面,最基本的核心就是如何控制framebuffer的值
Display Technologies CRT LCD
Alpha and blending 透明度和混色,進行影像間的疊圖處理,增添影像效果
Draw image
Alpha An alpha channel, representing transparency information on a per-pixel basis. Alpha = 0.0f: fully transparent Alpha = 1.0f: fully opaque Alpha channel 可用來指定像素的透明度 0 表示完全透明 1 表示完全不透明
Chroma-keying (Primatte) 在電影特效上,常利用藍幕的方式,將前景與背景分離,由於背景的顏色單純,可以很容易的分出背景色,如圖右 也就是可以將顏色藍色的像素中的透明度指定為0
Writing Model Use A component of RGBA (or RGBa) color to store opacity During rendering we can expand our writing model to use RGBA values blend source blending factor destination component source component 混色的模型基本上就是 寫入的顏色值和已在framebuffer值的處理 Color Buffer destination blending factor
Blending glBlendFunc(Glenum S, Glenum D); Cf = (Cs*S) + (Cd*D) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); Ex: Cs={Rs, Gs, Bs, As}, Cd ={Rd, Gd, Bd, Ad}, Cf = (Cs*As) + (Cd*(1-As)) 透過混色方程式的設定,Cf代表混色後的結果,Cs代表將填入的顏色,Cd代表已經在畫面上(framebuffer)的顏色。 透過x跟d兩個係數可以調整出不同的混色結果。 常用的設定是,S代表填入顏色的透明度,D代表1減掉填入顏色的透明度,就會呈現像畫圖在透明投影片層層疊圖的效果 舉例而言 若Cs =(1, 1, 0, 0.6), Cd= (0.8, 0.4, 0.4, 0.3) Cf = (1, 1, 0) *(0.6) + (0.8, 0.4, 0.4)*(1-0.6) = (0.92, 0.56, 0.16)
Compositing F B C foreground color alpha matte background plate 延續在電影特效中混色的運用 對於前景的物體,先分離出alpha matte指定每個像素的透明度,並找好適當的背景 透過透明度合成出最後的結果,Cf = (Cs*As) + (Cd*(1-As)) 當等於0時就等於選擇背景的顏色 composite C F C compositing equation =0 B
Compositing F B C composite compositing equation =1 F C B 當等於1時就等於選擇前景的顏色 composite C F compositing equation C =1 B
Order Dependency Is this image correct? Probably not Polygons are rendered in the order they pass down the pipeline Blending functions are order dependent 處理透明色時要特別留意,由於混色公式一次處理兩個顏色的混色 當多個顏色混合時,容易因為繪圖先後順序的問題,兩兩混色後產生錯誤的結果 故需先對fragment或幾何物體先排好順序
Intersection
Axis-Aligned Bounding Boxes Specified as two points: Normals are easy to calculate Simple point-inside test:
Problems With AABB’s Not very efficient Rotation can be complicated Must rotate all 8 points of box Other option is to rotate model and rebuild AABB, but this is not efficient
(maxX, maxY) (minX, minY) function isPointInsideAABB(point, box) { return (point.x >= box.minX && point.x <= box.maxX) && (point.y >= box.minY && point.y <= box.maxY); } https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_collision_detection
function intersect(a, b) { return (a. minX <= b. maxX && a function intersect(a, b) { return (a.minX <= b.maxX && a.maxX >= b.minX) && (a.minY <= b.maxY && a.maxY >= b.minY); }
Bounce
Example [Bounce] void glutTimerFunc Key Function *Registers a timer callback to be triggered in a specified number of milliseconds. msecs : Number of milliseconds to pass before calling the callback. func : The timer callback function. value : Integer value to pass to the timer callback. void glutTimerFunc (unsigned int msecs, void(*func)(int value), int value); *此函數可設定GLUT等待msec.,然後呼叫func這個函數(可自訂),並於value參數中傳入自訂的值。
Bounce animation …
void TimerFunction(int value) { // Reverse direction left 、right 、top 、bottom edge if(x1>windowWidth-rsize || x1<0) xstep=-xstep; if(y1>windowHeight-rsize || y1<0) ystep=-ystep; //Check bounds if(x1>windowWidth-rsize) x1=windowWidth-rsize-1; if(y1>windowHeight-rsize) y1=windowHeight-rsize-1; //Actually move the square x1+=xstep; y1+=ystep; //Redraw the scene with new coordinates glutPostRedisplay(); glutTimerFunc(33,TimerFunction,1); //self recall per 33msecs. }