การชักตัวอย่าง

Download Report

Transcript การชักตัวอย่าง

418341 สภาพแวดล้อมการทางานคอมพิวเตอร์กราฟิ กส์
การบรรยายครั้งที่ 10
ประมุข ขันเงิน
Blending
• เวลาเรากาหนดสีด้วย glColor*(…) เราสามารถกาหนด alpha
ของสีได้ ด้วย
• Alpha มีไว้ ใช้ ควบคุมการทา blending
• Blending คือการคานวณสีของ pixel ใหม่เมื่อ fragment
ใหม่กาลังจะถูกเขียนลงบน framebuffer โดยนาเอาสีของ pixel
เดิมมาร่วมคานวณด้ วย
Blending (ต่อ)
• ที่เราเรี ยนผ่านมาใช้ วิธีการคานวณสีของ pixel สองแบบ
– เอาสีของ fragment ที่มาทีหลังเขียนทับลงบน framebuffer
– เก็บสีของ fragment ที่ใกล้ ตาที่สดุ เอาไว้ (z-buffer algorithm)
• OpenGL สามารถทาการคานวณสีได้ หลายแบบกว่านี ้มาก
• การคานวณสีหลายๆ แบบ ที่ไม่ใช่สองแบบข้ างบนนี ้เราก็เรี ยกตีขลุมว่า
blending
การใช้และเลิกใช้ blending
• เวลาจะทา blending ต้ องสัง่ คาสัง่
glEnable(GL_BLEND);
• เวลาจะเลิกทา blending (กลับไปใช้ z-buffer หรื อการวาดทับ)
ให้ สงั่
glDisable(GL_BLEND);
Source และ Destination
• เวลาทา blending จะมีข้อมูลสีที่เกี่ยวข้ องสองตัว
– Source คือ สี RGBA ของ fragment อันใหม่ที่กาลังจะถูกเขียนลง
บน pixel หนึง่ ของ framebuffer
– Destination คือ สี RGBA ของ pixel ที่อยูบ่ น framebuffer
เรี ยบร้ อยแล้ ว
• เราอาจคิดได้ วา่ destination คือสีที่คานวณจากสีของ
fragment ที่เกิดจากรูปร่างที่ถกู สัง่ วาดก่อน source ทังหมด
้
สมการ Blending
• การคานวณสีใหม่จะเป็ นไปตามสมการข้ างล่างนี ้
newcolor  ( Rs Sr  Rd Dr , Gs Sg  Gd Dg , Bs Sb  Bd Db , As Sa  Ad Da )
โดยที่
(Sr , S g , Sb , Sa ) คือสีของ source
( Dr , Dg , Db , Da ) คือสีของ destination
( Rs , Gs , Bs , As ) เรี ยกว่า “blending factor” ของ source
( Rd , Gd , Bd , Ad )
เรี ยกว่า “blending factor” ของ dest’
คาสัง่ กาหนด Blending Factor
• เราสามารถกาหนด blending factor ได้ ด้วยคาสัง่
glBlendFunc(GLenum src, GLenum dest)
และคาสัง่
glBlendFuncSeparate(
GLenum srcRGB, GLenum srcAlpha,
GLenum destRGB, GLenum destAlpha)
• สองฟั งก์ชนั นี ้ต่างกันตรงที่ glBlendFuncSeparate สามารถ
กาหนด blending factor โดยแยก RGB กับ A ออกจากกันได้
ค่าคงที่กาหนดสาหรับ Blending Factor
• ค่าที่ใส่ให้ argument แต่ละตัวเป็ นค่าคงที่ในตารางต่อไปนี ้
Constant
Relevant Factor
Computed Blend Factor
GL_ZERO
source or destination
(0, 0, 0, 0)
GL_ONE
source or destination
(1, 1, 1, 1)
GL_DST_COLOR
source
(Rd, Gd, Bd, Ad)
GL_SRC_COLOR
destination
(Rs, Gs, Bs, As)
GL_ONE_MINUS_DST_COLOR
source
(1, 1, 1, 1)-(Rd, Gd, Bd, Ad)
GL_ONE_MINUS_SRC_COLOR
destination
(1, 1, 1, 1)-(Rs, Gs, Bs, As)
GL_SRC_ALPHA
source or destination
(As, As, As, As)
GL_ONE_MINUS_SRC_ALPH A
source or destination
(1, 1, 1, 1)-(As, As, As, As)
GL_DST_ALPHA
source or destination
(Ad, Ad, Ad, Ad)
GL_ONE_MINUS_DST_ALPH A
source or destination
(1, 1, 1, 1)-(Ad, Ad, Ad, Ad)
GL_SRC_ALPHA_SATURATE
source
(f, f, f, 1); f=min(As, 1-Ad)
กาหนดเครื่ องหมายที่ใช้ในสมการ Blending
• เรายังสามารถเครื่ องหมายที่ใช้ รวมสีของ source กับ destination
เข้ าด้ วยกันได้ มันไม่จาเป็ นต้ องเป็ นเครื่ องหมายบวก
• เครื่ องหมายนี ้สามารถกาหนดได้ ด้วยคาสัง่
glBlendEquation(GLenum mode)
และ
glBlendEquationSeparate(GLenum modeRGB,
GLenum modeAlpha)
• เช่นเคย glBlendEquationSeparate สามารถกาหนดเครื่ องหมาย
ของ RGB และ A แยกกันได้
ค่าคงที่ในการกาหนดเครื่ องหมายในการทา blending
ค่ าคงที่
การคานวณสีใหม่
GL_FUNC_ADD
Cs S  Cd D
GL_FUNC_SUBTRACT
Cs S  Cd D
GL_FUNC_REVERSE_SUBTRACT
Cd D  Cs S
GL_MIN
min(Cs S , Cd D)
GL_MAX
max(Cs S , Cd D)
GL_LOGIC_OP
Cs S op Cd D
GL_LOGIC_OP
• กรณีที่ใช้ GL_LOGIC_OP คาว่า “op” จะถูกแทนด้ วย
เครื่ องหมายทางตรรกศาสตร์ ซงึ่ สามารถกาหนดได้ ด้วยคาสัง่
glLogicOp()
ตัวอย่าง: Matting
• การนารูปสองรูปมาซ้ อนกัน
• รูปที่อยูด่ ้ านหน้ าบาง pixel อาจมี alpha ไม่เป็ น 0 แสดงว่า
pixel โปร่งแสง ทาให้ เห็นรูปที่อยูข่ ้ างหลัง
• กรณีนี ้ให้ destination blending factor เป็ น
GL_ONE_MINUS_SRC_ALPHA
• และให้ source blending factor เป็ น GL_SRC_ALPHA
ดู demo
ตัวอย่าง: Billboarding
•
•
•
•
•
การสร้ างวัตถุคล้ ายสามมิติจากภาพ เช่น ต้ นไม้ เป็ นต้ น
ทาให้ ไม่ต้องวางสามเหลี่ยมจานวนมาก
ใช้ ภาพที่บาง pixel มี alpha เท่ากับ 0
จะว่าไปก็เหมือนทา matting ในสามมิติ
ให้ destination blending factor เป็ น
GL_ONE_MINUS_SRC_ALPHA
• และ source blending factor เป็ น GL_SRC_ALPHA
ตัวอย่าง: Billboarding (ต่อ)
ตัวอย่าง: การรวมรู ปสามรู ปเข้าด้วยกัน
• ให้ destination blending factor เป็ น GL_ONE
• ให้ source blending factor เป็ น GL_SRC_ALPHA
• วาดรูปแต่ละรูปด้ วย alpha = 1/3
ตัวอย่าง: ปรับสี RGB
• วาดภาพภาพหนึง่ ลงบน framebuffer โดยไม่ต้องทา
blending
• หลังจากนันใช้
้ destination blending factor เป็ น
GL_SRC_COLOR
• และใช้ source blending factor เป็ น GL_ZERO
• หลังจากนันวาดสี
้
เหลี่ยมสีเดียวทับลงบนภาพนัน้
การวาดวัตถุโปร่ งแสงในสามมิติ
•
•
•
•
ต้ องวาดวัตถุทบึ แสดงให้ หมดก่อนโดยใช้ depth buffer
หลังจากนันเปิ
้ ด blending
แล้ ววาดวัตถุโปร่งแสง
ข้ อควรระวัง 1: เพื่อให้ ได้ ภาพที่ถกู ต้ อง เราต้ องวาดวัตถุโปร่งแสงจาก
ด้ านหลังไปด้ านหน้ า
การวาดวัตถุโปร่ งแสงในสามมิติ (ต่อ)
• ข้ อควรระวัง 2: เวลาวาดวัตถุโปร่งแสงจะต้ องทาการป้องกันไม่ให้ วตั ถุ
โปร่งแสงไปเปลี่ยนแปลง depth buffer
• เราสามารถทาให้ depth buffer ไม่ถกู เขียนทับได้ ด้วยการสัง่
glDepthMask(GL_FALSE);
• และทาให้ มนั ถูกเขียนทับได้ ใหม่อีกครัง้ (เพื่อวาดรูปวัตถุทบึ แสงใหม่)
ด้ วยคาสัง่
glDepthMask(GL_TRUE);
ดู demo
ดูโค้ด
glPushMatrix ();
glTranslatef (-0.15, -0.15, solidZ);
glMaterialfv(GL_FRONT, GL_EMISSION, mat_zero);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_solid);
glCallList (sphereList);
glPopMatrix ();
glPushMatrix ();
glTranslatef (0.15, 0.15, transparentZ);
glRotatef (15.0, 1.0, 1.0, 0.0);
glRotatef (30.0, 0.0, 1.0, 0.0);
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_transparent);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE);
glDepthMask (GL_FALSE);
glCallList (cubeList);
glDepthMask (GL_TRUE);
glDisable (GL_BLEND);
glPopMatrix ();
หมอก
• หมอกใน OpenGL ทาให้ pixel มีสีเปลี่ยนไปตามระยะห่างจากตา
• ทาให้ เกิด effect เหมือนหมอกจริงๆ ได้
• เวลาใช้ หมอกต้ องสัง่
glEnable(GL_FOG);
เวลาเลือกใช้ สงั่
glDisable(GL_FOG);
การคานวณหมอก
• การคานวณหมอกต้ องมี depth buffer เพื่อวัดระยะห่างจากตา
ดังนันต้
้ องมี GLUT_DEPTH ใน glutInitDisplay
• การคานวณหมอกจะทาหลังจาก render รูปขันตอนอื
้
่นทังหมด
้
• เวลาคานวณสีของ pixel เมื่อมีหมอกจะใช้ สตู รต่อไปนี ้
C  f Ci  (1  f ) C f
C คือสีของ pixel หลังจากคานวณแล้ ว
f คือ fog factor ที่จะบอกวิธีคานวณในสไลด์ตอ่ ไป
Ci คือสีของ pixel ใน frame buffer
Cf คือสีของหมอก
Fog Factor
• เราสามารถกาหนดวิธีการคานวณ fog factor ได้ โดยคาสัง่
glFogi(GL_FOG_MODE, GLenum mode)
โดย mode มีคา่ ได้ สามค่าดังต่อไปนี ้
– GL_EXP
f e
( density z )
( density z ) 2
– GL_EXP2
f e
– GL_LINEAR
end  z
f 
end  start
การเซตหมอกค่าต่างๆ
• เราสามารถเซตค่าสีของหมอกได้ โดยคาสัง่
glFogfv(GL_FOG_COLOR, Glfloat *color)
เช่น
float fog_color[4] = {0.5f, 0.5f, 0.5f, 1.0f};
glFogfv(GL_FOG_COLOR, fog_color);
การเซตหมอกค่าต่างๆ (ต่อ)
• เราสามารถเซตค่า density ของหมอก (ใช้ ในการคานวณกรณี
GL_EXP และ GL_EXP2) ได้ ด้วยคาสัง่
glFogf(GL_FOG_DENSITY, GLfloat density)
• เราสามารถเซตค่า start และ end (ใช้ ในการคานวณกรณี
GL_LINEAR) ได้ ด้วยคาสัง่
glFogf(GL_FOG_START, GLfloat start) และ
glFogf(GL_FOG_END, GLfloat end)
ตามลาดับ
ดู demo
การชักตัวอย่ างและการสร้ างคืน
ภาพดิจิตอล
• ประกอบด้ วย “พิกเซล” เรี ยงกันเป็ นตาราง
รูปจาก http://en.wikipedia.org/wiki/Pixel
พิกเซลคืออะไร?
• พิกเซลไม่ใช่
– กล่องสี่เหลี่ยม
– จุดวงกลม
– เส้ นขีด
รูปจาก http://en.wikipedia.org/wiki/Pixel
พิกเซลคืออะไร? (ต่อ)
• มันคือตัวเลขสามตัวแทนค่า RGB ณ จุดจุดหนึง่ บนระนาบภาพ
• “จุด” ที่วา่ นี ้
– ไม่มีขนาด ความกว้ าง ความยาว
– ไม่มีมิติ
– มองไม่เห็น
– มีแต่ “ตาแหน่ง”
ภาพคืออะไร?
• ฟั งก์ชนั จากระนาบสองมิติ R2 ไปยังความเข้ มแสง
• รูปภาพเป็ นฟั งก์ชนั ต่อเนื่อง
• สามารถมองว่าแต่ละจุดมีความสูงของมัน
ภาพดิจิตอล
• สร้ างโดยการหาค่าของฟั งก์ชนั ภาพ ณ จุดที่เรี ยงกันเป็ นตารางสี่เหลี่ยม
• กระบวนการทาเช่นนี ้เรี ยกว่า การชักตัวอย่ าง (sampling)
ภาพดิจิตอล (ต่อ)
การสร้างคืน
• เมื่อได้ ภาพดิจิตอล ซึง่ เป็ นตัวอย่างหลายๆ ตัวอย่างที่เราชักมาจากภาพ
• เราต้ องทาการสร้ างคืน (reconstruction) เพื่อให้ ได้ ฟังก์ชนั
ต่อเนื่องสองมิตอิ นั ใหม่
การสร้างคืน (ต่อ)
• เราต้ องการให้ ภาพที่เราสร้ างคืนเหมือนกับภาพต้ นแบบที่สดุ เท่าที่จะ
เป็ นไปได้
• ปกติแล้ วอุปกรณ์แสดงผลจะสร้ างภาพคืนให้ เราโดยอัตโนมัติ
• ส่วนมากด้ วยการวาดสีของตัวอย่างที่ชกั มาเป็ นสี่เหลี่ยม
เอเลียสซิง
• แต่การสร้ างคืนด้ วยการวาดเป็ นสี่เหลี่ยมนี่เองทาให้ เกิดปั ญหาตามมา
หลายอย่าง เรี ยกรวมๆ ว่า เอเลียสซิง (aliasing)
• ทาให้ ภาพออกมาดูไม่ดี จะดูไม่ดีมากโดยเฉพาะเวลาทาภาพเคลือ่ นไหว
เอเลียสซิง (ต่อ)
• ขอบเป็ นหยักๆ
เอเลียสซิง (ต่อ)
• รายละเอียดหายหรื อถูกขยายใหญ่เกินไป
เอเลียสซิง (ต่อ)
• จิตรกรรมฝาผนังดูไม่สวย
การแปลงฟูเรียร์
โดเมนความถี่
• ฟั งก์ชนั เกือบทุกฟั งก์ชนั สามารถเขียนอยูใ่ นรูปผลบวกของฟั งก์ชนั ไซน์
หรื อโคไซน์ได้
• ถ้ าเขียนในรูปแบบนี ้ เราเรี ยกว่ามันอยูใ่ น โดเมนความถี่
(frequency domain)
• ถ้ าเขียนแบบปกติจะเรี ยกว่าอยูใ่ น โดเมนปริภมู ิ (spatial
domain)
• นึกถึงเสียง ซึง่ เป็ นฟั งก์ชนั การเคลื่อนที่ของลาโพง
– เราสามารถเอาเสียงไปใส่ spectrum analyzer
– มันจะบอกว่าเสียงความถี่เท่านี ้มีความดังเท่าไหร่
โดเมนความถี่ (ต่อ)
• ฟั งก์ชนั ที่เปลี่ยนแปลงเร็ว มีความถี่สงู
• ฟั งก์ชนั ที่เปลี่ยนแปลงช้ า มีความถี่ต่า
โดเมนความถี่ (ต่อ)
• ฟั งก์ชนั ในโดเมนปริภมู ิ
ความถี่ต่า
ความถี่สงู
โดเมนความถี่ (ต่อ)
• เมื่ออยูใ่ นโดเมนความถี่
ขอบเขตแคบ
ขอบเขตกว้ าง
การแปลงฟูเรี ยร์ (ต่อ)
• เรามีฟังก์ชนั f (x) ในโดเมนปริภมู ิ
• การแปลงฟูเรี ยร์ ทาให้ เราได้ ฟังก์ชนั F (! ) ในโดเมนความถี่
• ความสัมพันธ์ระหว่างทังสองฟั
้
งก์ชนั :
Z
1
f (x)e¡
F (! ) =
i 2¼! x
dx
¡ 1
1
Z
F (! )ei 2¼! x d!
f (x) =
¡ 1
การแปลงฟูเรี ยร์ (ต่อ)
• เราใช้ สญ
ั ลักษณ์
F f f (x)g แทนการแปลงฟูเรี ยร์ ของ f (x)
Z1
F f f (x)g = F (! ) =
f (x)e¡ i 2¼! x dx
• การแปลงฟูเรี ยร์ เป็ นฟั งก์ชนั เชิงเส้ น
¡ 1
F f f (x) + g(x)g = F f f (x)g + F f g(x)g
F f cf (x)g = cF f f (x)g
การคูณและการแปลงฟูเรี ยร์
• ถ้ าเราทาการแปลงฟูเรี ยร์ ของผลคูณของฟั งก์ชนั สองฟั งก์ชนั
• เราจะได้ คอนโวลูชันของการแปลงฟูเรี ยร์ ของฟั งก์ชนั สองฟั งก์ชนั นัน้
F f f (x)g(x)g = F (! ) - G(! )
• ในทานองเดียวกัน
F f f (x) - g(x)g = F (! )G(! )
คอนโวลูชนั
• มีนิยามดังนี ้
Z
1
f (x) - g(x) = (f - g)(x) =
f (t)g(x ¡ t)dt
¡ 1
• มีความหมายเหมือนกับการ “เลื่อน” g(x) ไปคูณกับ f (x) ทีละค่าของ
แล้ วเอาผลลัพธ์ทงหมดมาบวกกั
ั้
นx
คอนโวลูชนั (ต่อ)
ทฤษฎีการชักตัวอย่ าง
ดิแรกเดลตาฟังก์ชนั
• สัญลักษณ์ ±(x)
• ฟั งก์ชนั ที่ทาคอนโวลูชนั กับอะไรก็ได้ คา่ ของฟั งก์ชนั นัน้
f (x) - ±(x) = f (x)
• ถ้ าเลื่อน
±(x)
แล้ ว
f (x)
ก็จะเลื่อนตามไปด้ วย
f (x) - ±(x ¡ t) = f (x ¡ t)
ดิแรกเดลตาฟังก์ชนั (ต่อ)
• หน้ าตาของมัน
• หาค่าจริงไม่ได้ แต่ร้ ูวา่ integrate
แล้ วได้ 1
Z
1
±(x) dx = 1
¡ 1
การชักตัวอย่าง
• คือการเอาฟั งก์ชนั ภาพมาคูณกับดิเรกเดลตาฟั งก์ชนั ที่วา่ งไว้ ห่างเป็ น
ระยะเท่าๆ กัน
ชาฮ์ฟังก์ชนั
• ดิเรกเดลตาฟั งก์ชนั ที่เอามาเรี ยงห่างกันเป็ นระยะเท่าๆ กันมีชื่อเรี ยกว่า
ชาฮ์ ฟังก์ ชัน (Shah) หรื อ หวีของดิแรก (Dirac comb)
• สัญลักษณ์ III T (x)
X1
I I I T (x) = T
±(x ¡ kT)
k= ¡ 1
• โดยค่า
T
คือ “คาบ” ของฟั งก์ชนั
ชาฮ์ฟังก์ชนั (ต่อ)
ชาฮ์ฟังก์ชนั (ต่อ)
• เมื่อนาชาฮ์ฟังก์ชนั ที่มีคาบ T ไปทาการแปลงฟูเรี ยร์ จะได้ ชาฮ์ฟังก์ชนั
ที่มีคาบ 1=T
1
1 X
F f I I I T (x)g =
T
k= ¡ 1
±(! ¡ k=T) = I I I 1=T (! )
การชักตัวอย่าง (อีกครั้ง)
• ดังนันการชั
้
กตัวอย่างทุกๆ คาบ
สัญลักษณ์ได้ วา่
T
สามารถเขียนเป็ นประโยค
f (x)III T (x)
• การแปลงฟูเรี ยร์ ของฟั งก์ชนั ข้ างบนคือ
F f f (x)III T (x)g = F (! ) - III 1=T (! )
การชักตัวอย่าง (อีกครั้ง)
• เราทาการคูณ f (x) กับ III T (x) ในโดเมนปริภมู ิ
• เราจะลองเขียนฟั งก์ชนั และผลลัพธ์ที่เกิดขึ ้นกับมันของการคูณในโดเมน
ความถี่ดู
• ย ้าว่าเราไม่ได้ ต้องแปลงฟั งก์ชนั เหล่านี ้ให้ อยูใ่ นโดเมนความถี่จริงๆ
ฟั งก์ชนั ทุกฟั งก์ชนั เขียนอยูใ่ นโดเมนความถี่ได้ อยูแ่ ล้ ว เราแค่ดเู ฉยๆว่า
ถ้ าเขียนอยูใ่ นโดเมนความถี่แล้ วเกิดอะไรขึ ้น
การชักตัวอย่าง (ต่อ)
• สมมติวา่ ฟั งก์ชนั f (x) ในโดเมนความถี่คือ F (! )
• และให้ F (! ) มีหน้ าตาเช่นนี ้
• การคูณ f (x) กับ III T (x) ในโดเมนปริภมู ิ
มีคา่ เท่ากับการเอา F (! ) กับ III 1=T (! ) มาทาคอนโวลูชนั กัน
การชักตัวอย่าง (ต่อ)
• เมื่อเอามันมาทาคอนโวลูชนั กับ
-
III 1=T (! )
จะได้
การชักตัวอย่าง (ต่อ)
• แล้ วตอนนี ้เราได้ อะไรบ้ าง
• เรารู้วา่ หลังจากการชักตัวอย่างแล้ ว เราจะได้ ฟังก์ชนั f (x)III T (x) ที่มี
หน้ าตาคล้ ายๆ รูปข้ างล่างในโดเมนปริภมู ิ
• กล่าวคือมันเป็ นดิแรกเดลตาฟั งก์ชนั ความสูงต่าต่างกันเรี ยงกันเป็ น
ช่วงๆ
การชักตัวอย่าง (ต่อ)
• แต่ถ้าเราเขียนฟั งก์ชนั ดิแรกเดลตาสูงๆ ต่าในโดเมนความถี่ เราจะได้
ซึง่ มีลกั ษณะเหมือนเอาฟั งก์ชนั ต้ นฉบับ F (! ) ในโดเมนความถี่มาถ่าย
เอกสารแล้ วแปะเป็ นช่วงๆ ระยะห่างเท่ากัน
การชักตัวอย่าง (ต่อ)
• ข้ อสังเกต:
– ดิแรกเดลตาฟั งก์ชนั แต่ละตัวในโดเมนปริภมู ิจะห่างกันเป็ นระยะ T
– แต่จดุ ศูนย์กลางของฟั งก์ชนั F (! ) แต่ละตัวในโดเมนความถี่จะห่างกันเป็ น
ระยะ 1=T
– ยิ่งเราสุม่ ถี่ขึ ้นเท่าไหร่ ก็อปปี ข้ องฟั งก์ชนั F (! ) ก็จะห่างขึ ้นไปเรื่ อยๆ
การชักตัวอย่าง (ต่อ)
• เรากล่าวว่าฟั งก์ชนั f (x) เป็ นฟั งก์ชนั ความถี่จากัด (band limit)
ถ้ าเราเขียนมันอยูใ่ นโดเมนความถี่ F (! ) แล้ วมันจะมีคา่ เป็ น F (! ) ถ้ า !
มีคา่ สูงถึงระดับหนึง่
• กล่าวคือมี B (ย่อมาจากคาว่า band)ที่ทาให้ F (! ) = 0 ถ้ า j! j > B
¡ B
B
การชักตัวอย่าง (ต่อ)
• ถ้ า f (x) มีความถี่จากัด และถ้ า T มีคา่ น้ อยพอ ก็อปปี ข้ อง F (! ) จะ
อยูห่ ่างกันและไม่ซ้อนทับกัน
• แต่ถ้า T มีคา่ มากเกินไป (เราชักตัวอย่างไม่ถี่พอ) ก็อปปี ข้ อง F (! )
อาจซ้ อนทับกันได้
การชักตัวอย่าง (ต่อ)
•
•
•
•
แล้ วต้ องเลือก T ให้ มีคา่ เท่าไหร่ ถึงจะได้ ก็อปปี ท้ ี่ไม่ซ้อนทับกัน?
คาตอบคือต้ องเลือกให้ 1=T > 2B
นัน่ คือต้ องสุม่ ให้ ถี่กว่าความถี่สงู สุดของ f (x) สองเท่า
ความถี่นี ้เรี ยกว่า ความถี่ไนควิสท์ (Nyquist Frequency)
การชักตัวอย่าง (ต่อ)
B
B
1=T
การสร้างกลับ
• ในการสร้ างกลับ เราต้ องการเอาฟั งก์ชนั ที่ชกั ตัวอย่างมาแล้ วมาทาอะไร
สักอย่างให้ ได้ ฟังก์ชนั ที่คล้ ายฟั งก์ชนั ต้ นฉบับมากที่สดุ
• สมมติวา่ ฟั งก์ชนั ต้ นฉบับมีความถี่จากัด และเราตัวอย่างมันที่ความถี่สงู
กว่าความถี่ไนควิสท์ ปั ญหาของเราคือ
ทาอย่างไรจะได้
จาก
?
การสร้างกลับ (ต่อ)
• ต้ องลบส่วนเกินที่อยูร่ อบนอกออกไป
• คูณด้ วย “กล่อง” ในโดเมนความถี่
£
ฟังก์ชนั กล่อง
• สัญลักษณ์
¦
T (!
)
(
¦
T (! ) =
1=(2T )
0
j! j < T
ot herwise
1=(2T)
¡ T
T
ซิงค์ฟังก์ชนั
• ฟั งก์ชนั กล่องที่วา่ มานันอยู
้ ใ่ นโดเมนความถี่ ถ้ าทาให้ อยูใ่ นโดเมนปริภมู ิ
แล้ วจะมีหน้ าตาเป็ นอย่างไร?
F ¡ 1f ¦
• โดยที่
T (x)g =
sinc(Tx)
(
sinc(x) =
1;
x= 0
sin x=x; ot herwise
การสร้างกลับ (ต่อ)
การสร้างกลับ (ต่อ)
• เขียนการสร้ างกลับจากการชักตัวอย่างเป็ นประโยคสัญลักษณ์ในโดเมน
ความถี่ได้ วา่
(F (! ) - I I I 1=T (! ))¦
T (!
)
• เมื่อเขียนอยูใ่ นโดเมนปริภมู ิ จะได้ เป็ น
(f (x)I I I T (x)) - sinc(Tx)
• ดังนัน้ การสร้ างกลับคือการเอาฟั งก์ชนั ที่ชกั ตัวอย่างมาแล้ วมาทาคอน
โวลูชนั กับซิงค์ฟังก์ชนั
การสร้างกลับ (ต่อ)
• ถ้ า f (x) มีความถี่จากัดและเราชักตัวอย่างด้ วยความถี่สงู กว่าความถี่
ไนควิสท์ของมัน เราจะสามารถสร้ างฟั งก์ชนั f (x) กลับคืนได้ เนื่องจาก
(F (! ) - I I I 1=T (! ))¦
T (!
) = F (! )
ดังนัน้
(f (x)I I I T (x)) - sinc(Tx) = f (x)
การสร้างกลับ (ต่อ)
• แต่ถ้าเราชักตัวอย่างด้ วยความถี่ต่ากว่าความถีไ่ นควิสท์ ก็อปปี ข้ อง F (! )
จะซ้ อนทับกัน และเมื่อคูณด้ วยฟั งก์ชนั กล่องจะได้ ฟังก์ชนั อีกอันหนึง่ ที่
ไม่เหมือน F (! ) ทุกประการ
การสร้างกลับ (ต่อ)
• ความไม่เหมือนกันทุกประการที่เกิดจากการชักตัวอย่างด้ วยความถี่ไม่
มากพอนี่เองที่เป็ นสาเหตุของเอเลียสซิงทังหมด
้
ฟั งก์ชนั ต้ นแบบ
ฟั งก์ชนั ที่สร้ างคืนที่มีเอเลียสซิง
การบรรเทาเอเลียสซิง
เอเลียสซิง
• เอเลียสซิงเวลาทาการสร้ างภาพสามมิตเิ กิดขึ ้นจาก
– ฟั งก์ชนั ภาพเป็ นฟั งก์ชนั ความถี่ไม่จากัด เนื่องจากมีความไม่ตอ่ เนื่องของสี ณ
ขอบเขตของวัตถุและเงา
– จิตรกรรมฝาผนังมีความไม่ตอ่ เนื่อง
เอเลียสซิง (ต่อ)
• เอเลียสซิงที่เกิดจากขอบเขตของวัตถุ
เอเลียสซิง (ต่อ)
• เอเลียสซิงที่เกิดจากความไม่ตอ่ เนื่องของจิตรกรรมฝาผนัง
เอเลียสซิง (ต่อ)
• ปกติแล้ วการบรรเทาเอเลียสซิงจากความไม่ตอ่ เนื่องของรูปทรงและเงา
ทาได้ ยาก
– ความไม่ตอ่ เนื่องของรูปทรงและเงาเป็ นฟั งก์ชนั ที่มีความถี่ไม่จากัด
– เราไม่สามารถลบส่วนความถี่ไม่จากัดนี ้ออกไปได้
• แต่การบรรเทาเอเลียสซิงจากความไม่ตอ่ เนื่องของจิตรกรรมฝาผนังทา
ได้ ง่ายกว่า
– เพราะเราสามารถดัดแปลงรูปเพื่อลบส่วนที่มีความถี่สงู ออกไปได้ ก่อนนามัน
มาใช้ คานวณสี
เทคนิคการบรรเทาเอเลียสซิงทัว่ ๆ ไป
• เพิ่มความถี่การชักตัวอย่าง (วาดให้ ละเอียดขึ ้น)
– ใช้ ได้ ผลดี แต่ไม่คอ่ ยคุ้มค่าเพราะต้ องเสียวาดเพิ่มขึ ้น
• ชักตัวอย่างแบบสุม่ ๆ
– แทนที่จะชักตัวอย่างแบบเป็ นตารางมีระเบียบ ก็ชกั ให้ มนั หลุดๆ ออกไปจาก
ตาแหน่งที่มนั ควรจะเป็ นสักเล็กน้ อย แบบสุม่ ๆ
– ทาให้ ภาพมีคลื่นรบกวนเยอะขึ ้น แต่เอเลียสซิงก็ถกู เปลี่ยนเป็ นคลื่นรบกวน
ด้ วย ทาให้ ภาพดูสบายตาขึ ้น
เทคนิคการบรรเทาเอเลียสซิงทัว่ ๆ ไป (ต่อ)
• เพิ่มความถี่การชักตัวอย่างโดยอาศัยการเรี ยนรู้จากภาพ
– ถ้ าภาพส่วนไหนมีความเปลี่ยนแปลงสีมาก ก็ให้ สมุ่ มากขึ ้น
• ส่วนขอบของวัตถุ
• จุดสองจุดที่อยู่ข้างกันที่สีต่างกันมากๆ
– ลดการคานวณลงได้ พอสมควร แต่ก็มีข้อบกพร่อง
• จุดสองจุดที่อยู่ติดกันบางคู่ อาจจะมีสีต่างกันมาก แต่ความจริ งไม่ต้องสุม่ เพิ่มก็ได้ เช่น
จุดสองจุดข้ างกันที่สีต่างกันเนื่องจากจิตรกรรมฝาผนัง
• บริ เวณที่ต้องการความถี่การสุม่ สูงอาจจะไม่ถกู สุม่ ความถี่สงู ขึ ้นก็ได้
การชักตัวอย่างแบบ “มัว่ ในบล็อก”
• ปกติเราจะชักตัวอย่างโดยในแต่ละพิกเซลเราจะยิง “รังสี” ไปที่กลาง
พิกเซลนัน้
• แต่มนั ทาให้ เกิดเอเลียสซิงได้ ง่าย
การชักตัวอย่างแบบ “มัว่ ในบล็อก” (ต่อ)
• เราสามารถชักตัวอย่างแบบมัว่ ๆ เพื่อเปลี่ยนเอเลียสซิงเป็ นคลื่นรบกวน
• แต่แบบนี ้บางพิกเซลจะไม่ถกู ชักตัวอย่างออกมาเลย
การชักตัวอย่างแบบ “มัว่ ในบล็อก” (ต่อ)
• เราสามารถรวมสองวิธีข้างต้ นเข้ าด้ วยกัน โดยในแต่ละพิกเซลเราจะชัก
ตัวอย่างมาหนึง่ ตัว แต่ตาแหน่งของตัวอย่างนันจะมั
้ ว่ เอา
• วิธีนี ้เป็ นวิธีชกั ตัวอย่างที่ได้ ผลดีมาก
การชักตัวอย่างแบบ “มัว่ ในบล็อก” (ต่อ)
• ภาพในอุดมคติ คานวณด้ วยการชักตัวอย่าง 256 ตัวอย่างในหนึ่ง
พิกเซล
การชักตัวอย่างแบบ “มัว่ ในบล็อก” (ต่อ)
• 1 ตัวอย่างต่อหนึง่ พิกเซล
การชักตัวอย่างแบบ “มัว่ ในบล็อก” (ต่อ)
• มัว่ ในบล็อก หนึง่ ตัวอย่างต่อหนึง่ พิกเซล
การชักตัวอย่างแบบ “มัว่ ในบล็อก” (ต่อ)
• มัว่ ในบล็อก 4 ตัวอย่างต่อหนึง่ พิกเซล
ฟิ ลเตอร์ การสร้ างกลับ
การสร้างกลับ (อีกรอบ)
• การสร้ างภาพกลับคือการนาเอาฟั งก์ชนั ที่ชกั ตัวอย่างออกมาแล้ วมาทา
คอนโวลูชนั กับฟั งก์ชนั ตัวหนึง่
• ฟั งก์ชนั ตัวนี ้เราจะเรี ยกว่า เคอร์ เนล (kernel) หรื อ ฟิ ลเตอร์
(filter)
• เรารู้วา่ ฟั งก์ชนั ซิงค์เป็ นฟั งก์ชนั การสร้ างกลับในอุดมคติ
– มันสามารถสร้ างฟั งก์ชนั เดิมออกมาได้ ถ้าเราชักตัวอย่างด้ วยความถี่สงู กว่า
ความถี่ไนควิสท์
การสร้างกลับ (ต่อ)
• แต่จริงๆ เวลาจะแสดงผล เราไม่ได้ สร้ างฟั งก์ชนั ต่อเนื่องต้ นฉบับกลับแต่
อย่างไร
• เวลาเราสัง่ จอภาพให้ แสดงภาพ หรื อจะเซฟภาพลงในไฟล์ เราต้ องส่ง
ตัวอย่างของฟั งก์ชนั ไปให้ จอภาพหรื อดิสก์อยูด่ ี
• ตัวอย่างที่จะส่งให้ จอภาพหรื อดิสก์ เป็ นตัวอย่างที่จดุ ของมันเรี ยงกัน
เป็ นระเบียบ หนึง่ ตัวอย่างต่อหนึง่ พิกเซล
• แต่ตอนเราชักตัวอย่าง เราอาจไม่ได้ ชกั ตัวอย่างแบบนัน้ (ถ้ าชักแบบนัน้
ก็แล้ วไป ไม่ต้องทาอะไร)
• บางที เราอาจชักตัวอย่างมากกว่าหนึง่ ตัวอย่างในหนึง่ พิกเซล
การสร้างกลับ (ต่อ)
เราอาจจะชักตัวอย่างแบบนี ้
แต่ตวั อย่างที่ต้องส่งให้ จอภาพเป็ นแบบนี ้
การสร้างกลับ (ต่อ)
• สิง่ ที่เราต้ องทาคือต้ องหาค่าของตัวอย่างที่ชกั มาอย่างเป็ นระเบียบ หนึง่
ตัวอย่างต่อหนึง่ พิกเซล จากตัวอย่างที่เราชักมาจริงๆ ซึง่ อาจไม่คอ่ ยเป็ น
ระเบียบนัก หรื ออาจมีมากกว่าหนึง่ ตัวต่อหนึง่ พิกเซล
การสร้างกลับ (ต่อ)
• การหาค่าที่วา่ นี ้เราจะนาเอาตัวอย่างที่อยูใ่ กล้ ๆ จุดที่เราต้ องการหาค่า
ฟั งก์ชนั มาถ่วงน ้าหนักแล้ วเฉลี่ย
P
I (x; y) =
โดยที่
i
f (x ¡ x i ; y ¡ yi )L(x i ; yi )
P
i f (x ¡ x i ; y ¡ yi )
คือฟิ ลเตอร์
L(¢; ¢) คือค่าความเข้ มแสงที่ได้ จากการยิงเรย์
I (¢; ¢) คือค่าความเข้ มแสงที่เราต้ องการหา
f (¢; ¢)
การสร้างกลับ (ต่อ)
ฟิ ลเตอร์
• เราใช้ ซงิ ค์ฟังก์ชนั เป็ นฟิ ลเตอร์ ไม่ได้
– มันมีขอบเขตกว้ างเกินไป หมายความว่าจะต้ องใช้ ตวั อย่างทุกตัวที่สมุ่ มา
– นอกจากนี ้มันยังอาจทาให้ เกินคลื่นกระเพื่อม (ringing) ในภาพได้ ถ้ า
ตัวอย่างที่สมุ่ มาความถี่ต่ากว่าความถี่ไนควิสท์
ฟิ ลเตอร์ (ต่อ)
• ฟิ ลเตอร์ ที่คนนิยมใช้ ได้ แก่
– กล่อง
– สามเหลี่ยม
– เกาส์
– มิทเชล
– ซิงค์แบบถูกจากัดขอบเขต (แลงค์ซอส
กล่อง
เอเลียสซิงเต็มไปหมด
สามเหลี่ยม
เรี ยบและเบลอ
เกาส์
เบลอมากๆ
มิทเชล
คมกว่าเกาส์
ซิงค์แบบถูกจากัดขอบเขต
ANTI-ALISING ใน OPENGL
Antialiasing ใน OpenGL
• การทา antialiasing ของจุดและเส้ น
• การทา multisampling
การทา antialiasing ของจุดและเส้น
• ถ้ าต้ องการทา antialiasing ของจุดให้ สงั่
glEnable(GL_POINT_SMOOTH);
• ถ้ าต้ องการทา antialiasing ของเส้ นให้ สงั่
glEnable(GL_LINE_SMOOTH);
• เมื่อถ้ าจะเลิกใช้ ให้ สงั่ glDisable(…) ตามสมควร
การทา antialiasing ของจุดและเส้น (ต่อ)
• การทา antialiasing ของจุดและเส้ นใน OpenGL เป็ นการ
กาหนดค่า alpha ของ fragment ที่ประกอบขึ ้นเป็ นจุดหรื อเส้ น
นัน้
• ค่า alpha ถูกคานวณด้ วย unweighted area sampling
• ดังนันถ้
้ าจะทา antialiasing จะต้ อง
– สัง่ glEnable(GL_BLENDING);
– และสัง่ glBlendFunc(…) ให้ เหมาะสม
การทา antialiasing ของจุดและเส้น (ต่อ)
• แล้ วจะสัง่ glBlendFunc อย่างไร?
• ปกติแล้ วใช้
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
• แต่ก็สามารถใช้
glBlendFunc(GL_SRC_ALPHA, GL_ONE)
เพื่อทาให้ จดุ ตัดสว่างขึ ้น
การทา antialiasing ของจุดและเส้น (ต่อ)
• ข้ อควรระวัง
– เนื่องจากเราใช้ blending ลาดับการวาดเส้ นและจุดจึงมีผลต่อรูป
– ถ้ ามีวตั ถุทบึ แสงอยูใ่ นฉากด้ วย
• ต้ องวาดวัตถุทบึ แสงให้ หมดก่อน แล้ วค่อยวาดเส้ นและจุด
• และจะต้ องมีการทาให้ depth buffer เป็ นแบบ readonly ด้ วย
• ดูรายละเอียดในการบรรยายครัง้ ที่ 16
ดู demo
การทา multisampling
•
•
•
•
สามารถใช้ ได้ กบั รูปทรงใดๆ ก็ได้
แต่เสียเวลาการทานานมาก
หลักการคือสร้ าง fragment เพิ่มขึ ้น 4 เท่า
แล้ วทาสร้ างภาพที่จะนาไปแสดงโดยให้ สีของ 1 fragment ของ
primitive ที่จะเอาไปแสดง เท่ากับค่าเฉลี่ยของสีของ 4
fragment (สี่เหลี่ยมกว้ าง 2 pixel ยาว 2 pixel) ของที่สร้ าง
ขึ ้นมา
ขั้นตอน
• เพิ่ม GLUT_MULTISAMPLE ลงใน
glutInitDisplayMode ดังนี ้:
glutInitDisplayMode(GLUT_DOUBLE |
GLUT_RGB | GLUT_DEPTH |
GLUT_MULTISAMPLE);
• เวลาใช้ ให้ สงั่ glEnable(GL_MULTISAMPLING);
ดู demo
ปัญหาการ compile บน Windows
• Multisampling เป็ นความสามารถใหม่ที่เพิ่มเข้ ามาใน
OpenGL เวอร์ ชนั หลังๆ
• แต่ OpenGL ที่มากับ Windows อยูท่ ี่เวอร์ ชนั 1.1 ซึง่ มีอายุ
ประมาณ 10 ปี แล้ ว
• ดังนันถ้
้ า compile โค้ ดตัวอย่างตามธรรมดาแล้ วจะพบว่ามันไม่ร้ ูจกั
ค่า GL_MULTISAMPLE
GLEW
• OpenGL Extension Wrangler (GLEW) เป็ นไลบรารี ที่
ใช้ ในการเข้ าถึงความสามารถของ OpenGL อันใหม่ๆ ที่ไม่มีใน
เวอร์ ชนั เก่า หรื อที่มีเฉพาะในฮาร์ ดแวร์ บางตัว
• สามารถ download มันได้ ที่
http://glew.sourceforge.net
• ให้ download Win32 binary ของมันมา แล้ วแตก zip ไฟล์
• นา glew32.dll ไปใส่ไว้ ที่ c:\windows\system32
• เสร็จแล้ วนา glew.h และ glew32.lib ไปใส่ไว้ ใน solution
ของโปรแกรมของเรา เช่นเดียวกับ GLUT
GLEW (ต่อ)
• เวลาใช้ งาน GLEW ให้ include ไฟล์ glew.h ก่อน glut.h
เช่น
#include <windows.h>
#include <GL/glew.h>
#include <GL/glut.h>