Harmonics & Light Probes ของ Spherical คืออะไร


14

สิ่งที่เป็นทรงกลมฮาร์มอนิและแสง Probes ? คอมพิวเตอร์กราฟิกมีประโยชน์อย่างไร? พวกเขาทำอะไรกันแน่ ฉันได้ยินคำว่าฮาร์โมนิกส์ทรงกลมและแสงโพรบทุกที่ตั้งแต่งานนำเสนอ siggraph ไปจนถึงบล็อกโพสต์

เมื่อเร็ว ๆ นี้ Matt Pettineo โพสต์บล็อกซีรี่ย์ 6 ตอนแต่ฉันก็ยังไม่เข้าใจว่ามันคืออะไร

เป็นอีกวิธีในการปรับปรุงแสงโดยรอบหรือไม่?

คำตอบ:


11

พื้นฐานของฮาร์มอนิกทรงกลม

Spherical Harmonics เป็นวิธีการแสดงฟังก์ชั่น 2D บนพื้นผิวของทรงกลม แทนที่จะเป็นโดเมนอวกาศ (เช่น cubemap), SH ถูกกำหนดไว้ในโดเมนความถี่ที่มีคุณสมบัติที่น่าสนใจและการดำเนินงานที่เกี่ยวข้องกับแสงที่สามารถดำเนินการได้อย่างมีประสิทธิภาพ ด้วยการเพิ่ม "ลำดับ" ของ SH คุณสามารถแสดงความถี่ที่สูงขึ้น (รายละเอียด) ของฟังก์ชั่นตามที่แสดงในภาพด้านล่าง (คือลำดับ SH) ด้วยการปรับและสรุป "ฟังก์ชั่นพื้นฐาน" ด้านล่างคุณสามารถเป็นตัวแทนของฟังก์ชั่น 2D ใด ๆ บนทรงกลมได้ถึงความถี่ที่กำหนดโดยฟังก์ชั่น ฟังก์ชั่นพื้นฐานที่กำหนดไว้ด้วย " เกี่ยวข้อง polynomials Legendre " แต่มักจะคุณไม่จำเป็นที่จะได้รับตัวเองเหล่านี้ แต่สามารถใช้การพิสูจน์ที่มีอยู่สำหรับดาวฤกษ์ประสานจริง lป้อนคำอธิบายรูปภาพที่นี่

การดำเนินการหนึ่งอย่างที่สามารถทำได้อย่างมีประสิทธิภาพใน SH เรียกว่า " convolution " ซึ่งหมายถึงการรวมผลิตภัณฑ์ของฟังก์ชัน 2D ทรงกลมสองแบบเข้ากับทรงกลม นี่คือการดำเนินการทั่วไปในการคำนวณแสงเช่นหนึ่งในฟังก์ชั่นอาจเป็นแสงที่ตกกระทบและฟังก์ชั่นหนึ่งของ BRDF เมื่อแสดงเป็น SH การดำเนินการนี้เป็นเพียงผลคูณของเวกเตอร์สัมประสิทธิ์ SH สองตัว

การดำเนินการที่น่าสนใจอีกอย่างหนึ่งคือความสามารถในการกรอง low-pass ที่มีประสิทธิภาพ เนื่องจาก SH มีการแสดงในโดเมนความถี่นี่เป็นเพียงเรื่องของการปรับขนาดหรือสัมประสิทธิ์สัมประสิทธิ์ SH บางส่วน การดำเนินการอื่น ๆ ในทางกลับกันอาจทำได้ยากใน SH เมื่อเทียบกับโดเมนเชิงพื้นที่เช่นหากคุณต้องการหมุนฟังก์ชั่นที่แสดงเป็น SH มันอาจมีราคาค่อนข้างแพงเมื่อสั่งซื้อ SH ที่สูงขึ้น ดังนั้นมันขึ้นอยู่กับปัญหาจริงๆถ้ามันเหมาะสมที่จะแสดงใน SH หรือไม่

โดยทั่วไปแล้ว SH จะใช้เพื่อแสดงเฉพาะฟังก์ชั่นความถี่ต่ำ (เช่นฟังก์ชั่นการเปลี่ยนแปลงที่ราบรื่น) เนื่องจากความถี่ที่สูงขึ้นนั้นต้องการการเพิ่มจำนวนของการจัดเก็บ (ค่าสัมประสิทธิ์ SH) และการประมวลผล นี่คือเหตุผลที่คุณไม่เห็นว่า SH ถูกนำมาใช้เป็นตัวอย่างในการแทนที่แสงสะท้อนบนพื้นผิวมันวาว นอกจากนี้ยังมีZonal Spherical Harmonicsซึ่งสามารถใช้เพื่อลดการจัดเก็บและการคำนวณสำหรับฟังก์ชัน 2D ที่มีความสมมาตรการหมุนเกี่ยวกับแกน z โดยเพียงแค่เก็บองค์ประกอบแนวทแยงของเมทริกซ์ SH สัมประสิทธิ์ นอกจากนี้ยังสามารถใช้Harmonics แบบครึ่งวงกลมได้หากคุณจำเป็นต้องจัดการกับฟังก์ชั่นแบบครึ่งวงกลม (เช่นกันในเรื่องแสง) ด้วยความได้เปรียบในการแสดงความถี่ที่ใกล้เคียงกับ SH ด้วยค่าสัมประสิทธิ์ที่น้อยลง

การดำเนินการหนึ่งที่คุณต้องดำเนินการคือ "SH projection" เพื่อแปลงข้อมูลโดเมนอวกาศเป็น SH คุณสามารถทำการดำเนินการนี้ได้ด้วยการทำข้อมูลโดเมนเชิงพื้นที่ด้วยฟังก์ชันพื้นฐาน SH คุณสมบัติที่น่าสนใจของ SH คือแตกต่างจากการแสดงโดเมนเชิงพื้นที่ SH ไม่ได้รับนามแฝงดังนั้นคุณจึงไม่ได้มีนามแฝงสิ่งประดิษฐ์แม้ในขณะที่ฉาย SH ต่ำมาก

หัววัดแสง

เมื่อคุณเข้าใจการดำเนินงานพื้นฐานและคุณสมบัติของ SH แล้วเราสามารถคิดวิธีนำไปใช้กับ GI หัววัดแสงบันทึกปริมาณแสงที่มาจากทุกทิศทางไปยังจุดที่หัววัดตั้งอยู่ นี่คือฟังก์ชัน 2D บนทรงกลมและสามารถแสดงเป็น SH (หรือ 3 ฟังก์ชั่น SH สำหรับสีแดงสีเขียวและสีน้ำเงิน) ขึ้นอยู่กับปริมาณของรายละเอียดแสงที่เราต้องการเข้ารหัสเป็นโพรบเราสามารถเลือกลำดับ SH

สำหรับโพรบแบบแสงที่ใช้สำหรับการกระจายแสงแบบ Lambertian เท่านั้นค่า SH ค่อนข้างต่ำนั้นเพียงพอเนื่องจากการสังเกตุนั้นทำด้วยโคไซน์ - พูซึ่งสามารถแทนด้วยลำดับ -2 SH (9 สัมประสิทธิ์) ค่าสัมประสิทธิ์ SH สำหรับโพรบแบบเบาสามารถสร้างได้ง่ายๆโดยการแสดง cubemap ที่จุดของโพรบแล้วฉายไปที่ SH

เมื่อเรนเดอร์เรขาคณิตจะมีโพรบวัดแสงที่ใกล้ที่สุดอยู่สองสามค่าและผลลัพธ์ถูกแก้ไขเพื่อให้ได้ฟังก์ชั่นแสงไฟตกกระทบในพื้นที่จุดหนึ่ง สิ่งนี้สามารถทำได้โดยการสอดแทรกค่าสัมประสิทธิ์ SH ของโพรบใกล้เคียงโดยตรงจากนั้นทำการสังเกตุด้วยพิกเซลโคไซน์กลีบในโดเมน SH


ประโยชน์ของการใช้วิธีนี้ผ่านการปรับแสงของภาพให้ง่ายขึ้นคืออะไร?
Arjan Singh

คุณสามารถมีแสงไฟความถี่ต่ำคุณภาพดีกว่าพร้อมการจัดเก็บและความต้องการด้านประสิทธิภาพที่คล้ายกันกว่าพูดโดยใช้ cubemaps
JarkkoL

16

เสียงประสานทรงกลม

ถ้าคุณรู้ว่าการแปลงฟูริเยร์คืออะไรคุณเกือบจะรู้ว่าฮาร์โมนิกทรงกลมคืออะไร: พวกมันคือการแปลงฟูริเยร์ แต่เป็นทรงกลมแทนที่จะเป็นเส้นตรง นั่นคือในขณะที่ฟูเรียร์เป็นวิธีที่แตกต่างกันของตัวแทนของฟังก์ชัน , ดนตรีทรงกลมเป็นสิ่งที่คล้ายคลึงสำหรับฟังก์ชั่นขั้วโลกพี)f ( θ , ϕ )f(x)f(θ,ϕ)

หากคุณไม่ทราบว่าการแปลงฟูริเยร์คืออะไรคุณต้องรู้ก่อนที่จะเข้าใจฮาร์โมนิกส์ทรงกลม การแปลงฟูริเยร์ช่วยให้คุณแสดงสัญญาณเป็นชุดคลื่นไซน์และคลื่นโคไซน์โดยแต่ละความถี่มีสองเท่าของความถี่สุดท้าย นั่นคือคุณสามารถแสดงสัญญาณเป็นค่าเฉลี่ยของมันรวมทั้งคลื่นไซน์ที่ความยาวคลื่นเท่ากับความยาวของสัญญาณบวกกับคลื่นไซน์สองเท่าของความยาวคลื่นและอื่น ๆ เนื่องจากการแปลงฟูริเยร์ช่วยคุณแก้ไขความยาวคลื่นเฉพาะเหล่านี้คุณจึงต้องบันทึกแอมพลิจูดของแต่ละอันเท่านั้น

โดยทั่วไปเราใช้การแปลงฟูริเยร์เพื่อแสดงภาพซึ่งเป็นเพียงสัญญาณดิจิตอล 2D มันมีประโยชน์เพราะคุณสามารถทิ้งคลื่นไซน์บางส่วน (หรือลดความแม่นยำที่คุณเก็บแอมพลิจูดของพวกเขาไว้) โดยไม่ต้องเปลี่ยนภาพที่ดูเหมือนกับดวงตาของมนุษย์ OTOH การทิ้งพิกเซลทำให้รูปลักษณ์ของภาพเปลี่ยนไปมาก

ในสัญญาณตัวอย่างเช่นภาพถ้าคุณใช้จำนวนคลื่นไซน์เท่ากันกับที่มีตัวอย่าง (พิกเซล) ในภาพต้นฉบับคุณสามารถสร้างภาพขึ้นมาใหม่ได้อย่างแน่นอนดังนั้นเมื่อคุณเริ่มทิ้งความถี่ใด ๆ ภาพใช้พื้นที่เก็บข้อมูลน้อย

เสียงประสานกลมเป็นเหมือนการแปลงฟูริเยร์ แต่แทนที่จะเป็นคลื่นไซน์พวกมันใช้ฟังก์ชันทรงกลมดังนั้นแทนที่จะเป็นฟังก์ชันเชิงเส้น (เช่นรูปภาพ) พวกมันสามารถแสดงฟังก์ชันที่กำหนดบนทรงกลม (เช่นแผนที่สภาพแวดล้อม)

หัววัดแสง

เช่นเดียวกับที่ภาพมาตรฐานบันทึกแสงทั้งหมดถึงจุดใดจุดหนึ่งผ่านระนาบภาพตัวตรวจจับแสงจะบันทึกแสงทั้งหมดที่ถึงจุดหนึ่งจากทุกทิศทาง พวกเขาออกมาจากเอฟเฟ็กต์ภาพยนตร์เป็นครั้งแรก หากคุณต้องการเพิ่มวัตถุที่สร้างจากคอมพิวเตอร์ให้กับฉากในโลกแห่งความเป็นจริงคุณจะต้องสามารถส่องแสงวัตถุสังเคราะห์ด้วยแสงในโลกแห่งความเป็นจริง ในการทำเช่นนั้นคุณต้องรู้ว่าแสงมาถึงจุดใดในฉากที่วัตถุสังเคราะห์จะเป็น (NB แม้ว่าฉันจะพูดว่า "แสง" คุณกำลังบันทึกภาพของแสงทั้งหมดดังนั้นมันจึงสามารถใช้สำหรับการสะท้อนแสงได้เช่นกัน)

เนื่องจากคุณไม่สามารถมีกล้องที่มีเลนส์ทรงกลมที่บันทึกแสงทั้งหมดถึงจุดเดียวจากทุกทิศทางคุณจึงบันทึกสิ่งนี้โดยการถ่ายภาพปกติของกระจกทรงกลมแล้วปฏิเสธภาพลงบนทรงกลม

นอกเหนือจากเอฟเฟ็กต์ภาพยนตร์เป็นเรื่องปกติที่จะใช้โพรบแบบเบาที่สร้างจากฉากประดิษฐ์ ลองจินตนาการว่าคุณมีอัลกอริทึมที่มีราคาแพงในการคำนวณการส่องสว่างระดับโลก (GI) ในฉากหนึ่งและคุณยังมีวัตถุขนาดเล็กบางชิ้นเคลื่อนที่ในฉากนี้ (เช่นระดับเกมกับผู้เล่นในนั้น) คุณไม่สามารถเรียกใช้อัลกอริทึม GI ทั้งหมดได้ทุกครั้งที่มีวัตถุเคลื่อนที่ดังนั้นคุณจึงเรียกใช้เพียงครั้งเดียวกับฉากแบบสแตติกและบันทึกโพรบเบา ๆ ที่จุดต่างๆ จากนั้นคุณสามารถประมาณค่า GI ที่ดีได้ด้วยการให้แสงผู้เล่นด้วยแสงใดก็ตามที่โพรบนั้นอยู่ใกล้

ใช้ร่วมกัน

โดยทั่วไปคุณต้องการกรองขอบที่คมชัดในการให้แสงสว่างทั่วโลกของคุณอยู่แล้วดังนั้นคุณจึงต้องการวิธีการแสดงให้เห็นถึงความกะทัดรัดและช่วยให้คุณทิ้งความถี่สูงได้อย่างง่ายดาย นั่นเป็นสิ่งที่กลมกลืนเป็นสิ่งที่ดีจริงๆ! นั่นเป็นเหตุผลที่คุณจะได้ยินคำศัพท์สองคำนี้ใช้กันมาก

คุณคำนวณโพรบเบาด้วยอัลกอริธึม GI ที่มีราคาแพงซึ่งโดยปกติจะเป็นเครื่องมือออกแบบระดับหรืออาจจะหนึ่งครั้งต่อวินาที (แทนที่จะเป็นหนึ่งครั้งต่อเฟรม) หากคุณต้องการรวมวัตถุแบบไดนามิกของคุณ คุณเก็บฮาร์โมนิกส์ทรงกลมราคาถูกเหล่านั้นไว้ด้วยกัน - 16 แพลทก็เพียงพอสำหรับการให้แสงสว่างคุณภาพสูง แต่ไม่สะท้อนแสง จากนั้นสำหรับวัตถุไดนามิกแต่ละรายการที่คุณต้องการให้แสงสว่างคุณจะเลือกหัววัดแสงที่ใกล้ที่สุด (หรือสอดแทรกเชิงเส้นหลาย ๆ เส้นด้วยกัน) และใช้เป็นชุดสัญญาณเข้าหรือสม่ำเสมอกับ shader นอกจากนี้ยังเป็นเรื่องธรรมดาที่จะใช้ฮาร์โมนิกทรงกลมเพื่อแสดงข้อมูลการบดเคี้ยวโดยรอบและมีราคาถูกมากที่จะโน้มน้าวใจพวกเขาด้วยเครื่องตรวจจับแสง


คำตอบที่ยอดเยี่ยมนี้ทำให้ทุกอย่างชัดเจนจริงๆ! ดังนั้นพื้น Probe แสงเป็นวิธีที่ง่ายในการคำนวณแสงในตัวละครเคลื่อนไหวซึ่งทำให้เราไม่สามารถคำนวณ GI สำหรับฉากทั้งหมด ฮาร์มอนิกส์ทรงกลมในทางกลับกันถูกใช้เพื่อกรองความถี่สูง (แก้ไขฉันถ้าฉันผิดฉันแค่พยายามดูว่าฉันมีความเข้าใจที่ถูกต้องหรือไม่)
Arjan Singh

"ถ้าคุณใช้คลื่นไซน์จำนวนเท่ากันกับที่มีตัวอย่าง (พิกเซล) ในภาพต้นฉบับคุณสามารถสร้างภาพขึ้นมาใหม่ได้ทุกประการ" จริง ๆ แล้วไม่จริง ตัวอย่างเช่นคลื่นสี่เหลี่ยมต้องการจำนวนความถี่ไม่ จำกัด สำหรับการแสดงที่แน่นอน
JarkkoL

@ JarkkoL แน่นอนว่าคลื่นสี่เหลี่ยมที่แท้จริงทำได้ แต่ถ้าคุณแยกมันออกโดยการสุ่มตัวอย่างคุณจะต้องใช้ความถี่เท่ากันเพื่อทำให้เกิดข้อผิดพลาดน้อยกว่าข้อผิดพลาดในการสุ่มตัวอย่าง มันเป็นผลลัพธ์ที่สะดวกของทฤษฎีบทของ Nyquist (ความถี่สูงสุดที่ปรากฏในสัญญาณตัวอย่างคือครึ่งหนึ่งของอัตราตัวอย่าง)
Dan Hulme

ใช่แล้วมันเป็นเรื่องจริง ฉันคิดว่าคุณต้องการความถี่ครึ่ง แต่ผลลัพธ์โดเมนความถี่ที่ซับซ้อน (เทียบกับจริง) หรือใช้ DCT และโดเมนจริงด้วยความถี่ของ DFT สองเท่า
JarkkoL

5

เสียงประสานทรงกลม

สมมติว่าคุณมีข้อมูลอยู่ในอาร์เรย์ แต่คุณต้องการแสดงข้อมูลนั้นด้วยจำนวนไบต์ที่น้อยลง

วิธีหนึ่งในการทำเช่นนั้นอาจเป็นการแสดงข้อมูลเป็นฟังก์ชันแทนที่จะเป็นค่า raw

คุณสามารถแทนมันเป็นฟังก์ชันเชิงเส้นได้: y=ax+b

จากนั้นแทนการจัดเก็บอาร์เรย์ของคุณของค่าที่คุณสามารถเก็บเพียงและขab

ปัญหาคือสมการเชิงเส้นอาจเป็นข้อมูลที่ไม่ดีพอ

คุณสามารถลองกำลังสองแทน: y=ax2+bx+c

ตอนนี้แทนการจัดเก็บและคุณเก็บ,และคb a b cababc

เราได้เพิ่มที่เก็บหน่วยความจำและความซับซ้อนในการคำนวณในการจัดเก็บและเรียกคืนข้อมูลของคุณเมื่อเทียบกับสมการเชิงเส้น แต่เป็นการประมาณที่ดีกว่าของอาร์เรย์ข้อมูลของคุณ เราสามารถใช้ฟังก์ชันลูกบาศก์ได้หรือสูงกว่าก็ได้ การเพิ่มคำสั่งซื้อเพิ่มการจัดเก็บการคำนวณและความแม่นยำ

ฮาร์โมนิกส์ทรงกลมเป็นวิธีการสร้างฟังก์ชั่นที่กำหนดไว้ในทรงกลมแทนที่จะเป็นเหมือนที่ฉันพูดถึงข้างต้นf(x)

เช่นเดียวกับในตัวอย่างด้านบนคุณสามารถใช้ฟังก์ชันฮาร์โมนิกส์ทรงกลมที่มีลำดับต่ำกว่าเพื่อสร้างบางสิ่งบางอย่างด้วยพื้นที่จัดเก็บที่ต่ำกว่าและการคำนวณที่ต่ำกว่าในการคำนวณข้อมูล แต่ยังลดความแม่นยำ

ในทางกลับกันคุณสามารถเพิ่มคำสั่งซื้อและรับข้อมูลที่ใกล้เคียงกับข้อมูลต้นฉบับของคุณได้ดีขึ้น แต่ด้วยค่าใช้จ่ายที่จำเป็นสำหรับพื้นที่เก็บข้อมูลที่มากขึ้นและการคำนวณที่จำเป็นในการคำนวณจุดข้อมูล

ในสุดขีดคุณสามารถใช้คำศัพท์ฮาร์มอนิกทรงกลมได้มากเท่าที่คุณมีตัวอย่างในอาเรย์แล้วคุณสามารถสร้างอาเรย์ดั้งเดิมของคุณใหม่ได้อย่างแน่นอน แต่คุณใช้การคำนวณจำนวนมากในการทำเช่นนั้น ตามที่คุณเริ่มต้นด้วย

ด้วยเหตุนี้ในทางปฏิบัติฟังก์ชันฮาร์โมนิกส์ทรงกลมจึงไม่ให้ประโยชน์มากนักหากคุณต้องการแสดงรายละเอียดที่ละเอียด - เช่นการสะท้อนที่คมชัดบนทรงกลม - แต่มันอาจมีราคาถูกสำหรับข้อมูลที่ไม่มีรายละเอียดที่ดี ไม่มีเนื้อหาที่มีความถี่สูงมาก) นอกจากนี้ยังมีประโยชน์สำหรับการคำนวณโดเมนความถี่เช่นการวิเคราะห์สเปกตรัมหรือการโน้มน้าว

หนึ่งในข้อมูลที่พวกเขาเก็บได้ดีคือ "irradiance" ซึ่งเป็นปริมาณของแสงที่กระทบกับจุดอื่น มันมีแนวโน้มที่จะดูเบลอเล็กน้อยซึ่งหมายความว่ามีเนื้อหาที่มีความถี่ต่ำเท่านั้นและเป็นตัวเลือกที่ดีสำหรับการจัดเก็บในฟังก์ชันฮาร์โมนิกส์ทรงกลม

ฉันจะทิ้งคำอธิบายไว้ให้คนอื่น: p


ทำไมถึงลงคะแนน? : P
Alan Wolfe

มันไม่เป็นความจริงเลยที่ฮาร์โมนิกส์ทรงกลมนั้นไม่สามารถแสดงรายละเอียดได้ดี เช่นเดียวกับการแปลงฟูริเยร์พวกเขาสามารถสร้างสัญญาณดั้งเดิมได้อย่างแน่นอนหากคุณรักษาความถี่ทั้งหมดไว้ เป็นเพียงการที่พวกเขาทำให้ประหยัดพื้นที่ได้ง่ายโดยการทิ้งความถี่สูงหากคุณไม่ต้องการ
Dan Hulme

และขออภัยฉันคิดว่าหลังจากลงคะแนนโหวตมันเป็นเรื่องรุนแรงที่จะลงคะแนนสำหรับการอ้างสิทธิ์ที่น่าสงสัยเพียงครั้งเดียวในคำตอบที่เป็นประโยชน์อย่างอื่น แต่การลงคะแนนของฉันถูกล็อคในเวลาที่ฉันมีความคิดที่สอง
Dan Hulme

อา. ใช่เป็นไปได้ในลักษณะเดียวกับที่เป็นไปได้ที่จะแสดงชุดข้อมูลใด ๆ ด้วยพหุนาม แต่ในทางปฏิบัติแล้วทั้งคู่เป็นตัวเลือกที่ไม่ดีสำหรับความต้องการใกล้เคียงกับจุดข้อมูลหลายจุด ด้วยพหุนามคุณต้องมี N เงื่อนไขของฟังก์ชันคำสั่ง N เพื่อให้พอดีกับจุดข้อมูล N เช่นซึ่งทำให้มันเป็นตัวเลือกที่แย่กว่าอาเรย์ตั้งแต่การคำนวณไม่ใช่การค้นหาเพื่อรับจุดข้อมูล ในทำนองเดียวกันในทางปฏิบัติฮาร์โมนิกทรงกลมเป็นตัวเลือกที่ไม่ดีสำหรับข้อมูลทรงกลมที่มีเนื้อหาความถี่สูงที่คุณต้องการรักษา มันไม่ใช่ทางเลือกที่ดีในสถานการณ์เหล่านั้น
Alan Wolfe

นั่นเป็นความจริงหากคุณต้องการสร้างตัวอย่างแต่ละตัวอย่างขึ้นใหม่ แต่ไม่ใช่การใช้ฟูริเยร์ทุกอย่างที่ต้องการ - ในทำนองเดียวกันสำหรับการใช้ SH ไม่ได้ทั้งหมด หากคุณกำลังจะทำการแปลงมันจะถูกกว่ามากในโดเมนความถี่ก่อนที่จะเปลี่ยนกลับไปเป็นตัวอย่าง คุณจะช่วยฉันเสนอการแก้ไขเพื่อให้คำตอบของคุณชัดเจนขึ้นหลังจากที่ฉันตอบคำถามเสร็จแล้วหรือไม่?
Dan Hulme
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.