《OpelGL編程指南第七版》第六章:混合、抗鋸齒、霧和多邊形(筆記)

《混合、抗鋸齒、霧和多邊形偏移》

標籤(空格分隔): OpenGL編程指南第七版


6.1 混合

image_1c3ig02611pr8bgqamm1u52suh9.png-98.8kB

6.1.1 源因子與目標因子

image_1c3ighn8615qrjocq6b1pb61m8lm.png-56.3kB
image_1c3igj1071lbee092o41op2bgh13.png-186.5kB
void glBlendFunc(GLenum srcfactor GLenum destfactor);
image_1c3igkq86od5lou1fe0pn524q9.png-120.3kB
image_1c3igl6noh64km21t5k1ek99kum.png-174kB

void glBlenndFuncSeparate(GLenum srcRGB, GLenum destRBG, GLenum srcAlpha, GLenum destAlpha);
image_1c3igodnp16ss19iu18d119nimn02j.png-131.1kB
image_1c3igop9vi81idsnel3bk16d930.png-35.8kB

void glBlendColor(GLclampdf red, GLclampdf green, GLclampdf blue, GLclampdf alpha);
image_1c3igs7ckbjuria1b4limb1l5k3t.png-47kB

6.1.2 啓用混合

glEnable(GL_BLEND);

6.1.3 使用混合方程式組合像素

void BlendEquation(GLenum mode);
image_1c3igvn6v10ga1m1910ehrtkmof4a.png-147kB

void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
image_1c3ih1j47loc1ttn1m813o2ekf4n.png-74.7kB

6.1.6 使用深度緩衝區進行三維混合

半透明物體繪圖順序將會極大地影響最終的結果。如果一個不透明的物體遮擋住了一個半透明的物體或者一個不透明的物體,就需要利用深度緩衝區消除這些距離更遠的物體。但是嗎,如果半透明物體更靠近觀察點,就需要把它與位於它後面的不透明物體進行混合。

這個問題的解決方案是啓用深度緩衝區。在繪製半透明物體時,讓深度緩衝區處於只讀狀態(半透明間需要注意繪圖順序,由遠及近)。

glDepthMask()傳遞GL_FALSE參數,深度緩衝區就設置爲只讀。

6.2 抗鋸齒

image_1c3jrau281q9o1sb91ttkc1f6669.png-456kB
void glHint(GLenum target, GLenum hint);對圖像質量和渲染速度之間的權衡關係施加控制。
image_1c3jrdk1f1u3lgh0rgr1gua1gc3m.png-360kB
image_1c3jrdulk1d2o1tia11umr14t6n13.png-123kB

6.2.1 對點和直線進行抗鋸齒處理

對點和直線進行抗鋸齒處理的一種方法之一是使用glEnable()函數(GL_POINT_SMOOTH或GL_LINE_SMOOTH)啓用抗鋸齒。
RGBA模式下的抗鋸齒
在RGB模式下,需要啓用混合功能。最常用的混合因子是GL_SRC_ALPHA(源)和GL_ONE_MINUS_SRC_ALPHA(目標)。另外也可以使用GL_ONE來表示目標混合因子。
由於所執行的是混合操作(glEnable(GL_BLEND)),可能需要考慮渲染順序。但是,在大多數情況下,可以忽略渲染順序,它不會產生明顯的不良效果。
image_1c3jri65broh17vr1h6lgvn1t281g.png-8.9kB
image_1c3jrjjp9rvc1jne78e127h2vq1t.png-10.6kB

顏色索引模式下的抗鋸齒
image_1c3jt7ea9vou6du9kt134bs2o2a.png-238.9kB

6.2.2 使用多重採樣對幾何圖元進行抗鋸齒處理

image_1c3ju968a1i3c1qsi18ic2v51poc2n.png-147.3kB
多重採樣特別適合對多邊形的邊緣進行抗鋸齒處理,因爲此時不需要進行排序
步驟:

  1. 獲取支持多重採樣的窗口
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_MUTISAMPLE);
  2. 驗證多重採樣功能是否可用
    如果查詢狀態變量GL_SAMPLE_BUFFERS返回的值是1,並且查詢GL_SAMPLES返回的值大於1,就可以使用多重採樣功能。
    GLint bufs,samples;
    glGetIntergerv(GL_SAMPLE_BUFFERS,&bufs);
    glGetIntergerv(GL_SAMPLES,&samples);
  3. 啓用多重採樣
    glEnable(GL_MULTISAMPLE);

圖片左側抗鋸齒,右側不抗鋸齒
image_1c3jukpa12id10r5n59am44dm34.png-159.1kB
image_1c3jumhgo1hbg1s651jr41vd21hon3h.png-169.6kB

alpha和多重採樣
在默認情況下,多重採樣計算的覆蓋值是獨立於alpha值的。但是,如果啓用了下面這些特殊的模式,那麼在計算片段的覆蓋值時,就會考慮alpha值的因素。

  • GL_SAMPLE_ALPHA_TO_COVERAGE:使用片段的alpha值來計算最終的覆蓋值。
  • GL_SAMPLE_ALPHA_TO_ONE:把片段的alpha值設置爲1,然後在計算覆蓋值時使用這個值。
  • GL_SAMPLE_COVERAGE:使用glSampleCoverage()函數所設置的值,這個值與經過計算產生的覆蓋值進行組合(使用AND操作)。另外,也可以通過在glSampleCoverage()函數中使用invert標誌來反轉這個模式。
    void glSampleCoverage(GLclampf value, GLboolean invert);
    image_1c3jvor9msul123c135j1kmvnl3u.png-93kB

6.2.3 對多邊形進行抗鋸齒處理

image_1c3k088it1c741jr11kin1ams4mk6r.png-142.9kB
image_1c3k0dnvupe41dccph71g5k8bi78.png-493.6kB

6.3 霧

霧是在執行了矩陣變換、光照和紋理之後才應用的。

6.3.1 使用霧

glEnable(GL_FOG);啓用霧
GLfloat fogColor4 = { 0.5, 0.5, 0.5, 1.0 };
fogMode = GL_EXP;
glFogi(GL_FOG_MODE, fogMode);
glFogfv(GL_FOG_COLOR, fogColor);
glFogf(GL_FOG_DENSITY, 0.35);
glHint(GL_FOG_HINT, GL_DONT_CARE);
glFogf(GL_FOG_START, 1.0);
glFogf(GL_FOG_END, 5.0);

6.3.2 霧方程式

image_1c3k19b95rfvh1r14ct14hq7r97l.png-164.2kB
void glFog{if}(GLenum pname, TYPE param);
void glFog{if}v(GLenum pname, TYPE* param);
image_1c3k1bof15umtmsmm1t9eku982.png-97.8kB
image_1c3k1cpph9lu1c3n1bhnn4r18nm9f.png-62.1kB

RGBA模式下的霧
image_1c3k1e9dsfri1k4524q1sa1ut99s.png-53.1kB

顏色索引模式下的霧
image_1c3k1epvllab12tvnc81jafcgra9.png-54.5kB

霧座標

image_1c3k33loatcm193213jkobu1he2am.png-197.3kB
void glFogCoord{fd}(TYPE z);
void glFogCoord{fd}v(const TYPE* z);
image_1c3k35ns0pgh361n831j6c1o9tb3.png-117.4kB
此時,視點移動對物體指定霧座標的頂點的霧效果沒有影響。

glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
image_1c3k43jhscpop8f1mnn1evflnfc0.png-15.4kB
image_1c3k446i14e113384001l11oskcd.png-34.2kB

glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
image_1c3k44tu2lroskd98k11gskhqcq.png-14kB
image_1c3k45aah1v8fm6kq5n88ifkbd7.png-24.5kB

6.4 點參數

點參數是一種自動、優雅的解決方案。它根據點和觀察點的距離,對點的大小和亮度進行衰減。
void glPointParameter{if}(GLenum pname, GLfloat param);
void glPointParameter{if}v(GLenum panme, const TYPE* param);
image_1c3mduhcc120k8r81j0vvrsbeu9.png-314.2kB

6.5 多邊形偏移

着重顯示實心物體的邊緣。
image_1c3me8mfkd11n74126o6cl1odbm.png-128.9kB
多邊形偏移可也以用於在表面上生成貼花、使用隱藏直線消除來渲染圖像。除了直線和多邊形外,這個技巧也可以用於點圖元。
使用glEnable()調用適當的參數(GL_POLYGON_OFFSET_FILL、GL_POLYGON_OFFSET_LINE、GL_POLYGON_OFFSET_POINT)來啓用多邊形偏移。還必須調用glPolygonMode()函數設置當前的多邊形光柵化方法。
void glPolygonOffset(GLfloat factor, GLfloat units);
image_1c3mejq91u8c168mcpfig1r3k23.png-114.9kB

image_1c3mfnnm81ga01r0gijo4421e2o2g.png-102.3kB
image_1c3mfqdm719mevop1pof1ium17vi3q.png-128.6kB
image_1c3mfq0cu15lt1bim1n6p1cd21n2t3d.png-140.7kB

factor = 0.1f,units = 0.0f
image_1c3mfsv568hr1j910491cl11qk947.png-46.2kB

factor = 0.1f,units = 536.0f
image_1c3mg21cmgh51gg718d11t7s17pd5k.png-43.1kB

factor = 1.4f,units = 0.0f
image_1c3mg37rsl591fihik51nff4d061.png-46.8kB

發佈了76 篇原創文章 · 獲贊 83 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章