อะไรคือสิ่งที่ล้ำสมัยสำหรับการแสดงผลข้อความใน OpenGL ตั้งแต่เวอร์ชัน 4.1? [ปิด]


199

มีคำถามจำนวนหนึ่งเกี่ยวกับการแสดงข้อความใน OpenGL เช่น:

แต่ส่วนใหญ่สิ่งที่กล่าวถึงคือการแสดงผลคณะสี่พื้นผิวโดยใช้ฟังก์ชั่นท่อคงที่ แน่นอนว่าผู้ที่จะต้องทำให้ดีขึ้น

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

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

  • รูปทรงเรขาคณิตที่ยอมรับเช่นตำแหน่งและทิศทางและลำดับของตัวละคร
  • รูปทรงเรขาคณิตที่แสดงแบบอักษรของเวกเตอร์
  • ดังกล่าวข้างต้น แต่ใช้เฉดสี tessellation แทน
  • ตัวคำนวณที่ใช้ในการทำ rasterization แบบอักษร

10
ฉันไม่สามารถตอบเกี่ยวกับสถานะของการเป็นหลักเป็นหลักในปัจจุบัน OpenGL ES ที่มุ่งเน้น แต่ tessellating TTF โดยใช้ GLU tesselator และส่งมันเป็นรูปทรงเรขาคณิตผ่านท่อฟังก์ชั่นการแก้ไขเก่ากับ kerning คำนวณบน CPU ให้ผลภาพที่ดี - กำจัดฮาร์ดแวร์และประสิทธิภาพที่ดีทั่วกระดานแม้กระทั่งเกือบทศวรรษที่ผ่านมา ดังนั้นไม่ใช่แค่กับตัวติดตั้งที่คุณสามารถหาวิธีที่ 'ดีกว่า' (ขึ้นอยู่กับเกณฑ์ของคุณ) FreeType สามารถแยกขอบเขต Bephier glyph และข้อมูลการจัดช่องไฟออกเพื่อให้คุณสามารถใช้งานได้จริงจาก TTF ในขณะใช้งานจริง
Tommy

QML2 (จาก Qt5) ทำเทคนิคที่น่าสนใจบางอย่างกับ OpenGL และฟิลด์ระยะทางเมื่อแสดงข้อความ: blog.qt.digia.com/blog/2012/08/08/native-look-text-in-qml-2
mlvljr

ดังนั้นฉันจะไม่สูญเสียมันอีกครั้งนี่คือห้องสมุดที่ใช้วิธีการระยะทางของ Valve code.google.com/p/glyphyฉันไม่ได้ลอง อาจจะคุ้มค่ากับการดู: code.google.com/p/signed-distance-field-font-generator
Timmmm

7
"off-topic" นี้เป็นคำสาปของสแต็กล้น อย่างจริงจัง?
Nikolaos Giotis

1
รุ่น "วิธีทำ" ที่ไร้เดียงสามากขึ้น: stackoverflow.com/questions/8847899/…
Ciro Santilli 郝海东冠状冠状病六四事件

คำตอบ:


202

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

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

ดูกระดาษ Valve ที่มีชื่อเสียงสำหรับเทคนิค

เทคนิคนี้คล้ายกับแนวคิดที่ว่าพื้นผิวโดยนัย (metaballs และอื่น ๆ ) ทำงานอย่างไรแม้ว่ามันจะไม่สร้างรูปหลายเหลี่ยม มันทำงานอย่างสมบูรณ์ในส่วนของ pixel shader และใช้ระยะทางที่สุ่มตัวอย่างจากพื้นผิวเป็นฟังก์ชันระยะทาง ทุกอย่างที่อยู่เหนือขีด จำกัด ที่เลือก (โดยปกติ 0.5) คือ "ใน" ทุกอย่างอื่นคือ "ออก" ในกรณีที่ง่ายที่สุดบนฮาร์ดแวร์ที่ไม่สามารถใช้งานร่วมกันได้ 10 ปีการตั้งค่าเกณฑ์การทดสอบอัลฟ่าเป็น 0.5 จะทำสิ่งนั้นอย่างแน่นอน (แม้ว่าจะไม่มีเอฟเฟกต์พิเศษและการลดรอยหยัก)
หากต้องการเพิ่มน้ำหนักให้กับฟอนต์เล็กน้อย (ตัวหนามารยาท) ขีด จำกัด ที่เล็กกว่าเล็กน้อยจะทำเคล็ดลับโดยไม่ต้องแก้ไขโค้ดบรรทัดเดียว (เพียงแค่เปลี่ยนชุด "font_weight" ของคุณ) สำหรับเอฟเฟกต์เรืองแสงเราจะพิจารณาทุกอย่างที่อยู่เหนือขีด จำกัด หนึ่งเป็น "ใน" และทุกอย่างที่อยู่เหนือขีด จำกัด (เล็กกว่า) อื่นเป็น "ออก แต่อยู่ในแสงส่องสว่าง" และ LERPs ระหว่างทั้งสอง การลดรอยหยักทำงานในทำนองเดียวกัน

ด้วยการใช้ค่าระยะทางที่เซ็นชื่อแบบ 8 บิตแทนที่จะเป็นบิตเดียวเทคนิคนี้จะเพิ่มความละเอียดที่มีประสิทธิภาพของแผนที่พื้นผิวของคุณ 16 เท่าในแต่ละมิติ (แทนที่จะเป็นสีขาวและดำใช้เฉดสีที่เป็นไปได้ทั้งหมด ข้อมูลโดยใช้ที่เก็บข้อมูลเดียวกัน) แต่แม้ว่าคุณจะขยายใหญ่เกิน 16x ผลลัพธ์ก็ยังดูน่ายอมรับ เส้นตรงที่ยาวจะกลายเป็นบิตเล็กน้อยในที่สุด แต่จะไม่มีสิ่งประดิษฐ์สุ่มแบบ "บล็อก" ทั่วไป

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

หากคุณแน่ใจว่าคุณไม่มีอักขระเกิน 256 ตัวอักษรในแบบอักษรของคุณอาร์เรย์ของพื้นผิวอาจมีค่าควรพิจารณาในการตัดแบนด์วิธบัสในลักษณะเดียวกันกับการสร้างล่ามจากจุดในรูปทรงเรขาคณิต เมื่อใช้พื้นผิวอาร์เรย์พิกัดพื้นผิวของคณะสี่คนทั้งหมดจะมีค่าคงที่sและtพิกัดเท่ากันและแตกต่างกันในrพิกัดซึ่งเท่ากับดัชนีอักขระที่จะแสดงผล
แต่เช่นเดียวกับเทคนิคอื่น ๆ ผลกำไรที่คาดหวังนั้นเป็นเพียงต้นทุนที่ไม่สอดคล้องกับฮาร์ดแวร์รุ่นก่อนหน้า

มีเครื่องมือที่มีประโยชน์โดย Jonathan Dummer สำหรับการสร้างพื้นผิวระยะทาง: หน้าคำอธิบาย

อัปเดต:
เมื่อไม่นานมานี้มีการดึงข้อมูลจุดยอดที่ตั้งโปรแกรมได้ (D. Rákos, "OpenGL Insights", pp. 239) ไม่มีความล่าช้าพิเศษหรือค่าใช้จ่ายเพิ่มเติมที่เกี่ยวข้องกับการดึงข้อมูลจุดสุดยอดทางโปรแกรมจาก shader บน GPU รุ่นใหม่ล่าสุด เมื่อเทียบกับการทำแบบเดียวกันโดยใช้ฟังก์ชั่นคงที่มาตรฐาน
นอกจากนี้ GPU รุ่นล่าสุดยังมีแคช L2 สำหรับใช้งานทั่วไปขนาดที่เหมาะสมมากขึ้น (เช่น 1536kiB บน nvidia Kepler) ดังนั้นหนึ่งอาจคาดหวังว่าปัญหาการเข้าถึงที่ไม่ต่อเนื่องกันเมื่อดึงค่าออฟเซ็ตแบบสุ่มสำหรับมุมสี่มุมจากพื้นผิวบัฟเฟอร์ ปัญหา.

สิ่งนี้ทำให้ความคิดในการดึงข้อมูลคงที่ (เช่นขนาดสี่เหลี่ยม) จากพื้นผิวบัฟเฟอร์น่าดึงดูดยิ่งขึ้น การดำเนินการตามสมมติฐานสามารถลดการถ่ายโอน PCIe และหน่วยความจำเช่นเดียวกับหน่วยความจำ GPU ให้น้อยที่สุดด้วยวิธีการเช่นนี้:

  • อัปโหลดเฉพาะดัชนีอักขระ (หนึ่งตัวต่ออักขระที่จะแสดง) เป็นอินพุตเดียวไปยังจุดยอดที่ส่งผ่านดัชนีนี้และgl_VertexIDและขยายไปถึง 4 จุดในรูปร่างเรขาคณิตยังคงมีดัชนีอักขระและจุดยอด id (นี่ จะเป็น "gl_primitiveID ให้บริการใน shader ที่" เป็นคุณลักษณะ แต่เพียงผู้เดียวและจับสิ่งนี้ผ่านการตอบรับการแปลง
  • สิ่งนี้จะเร็วเพราะมีเพียงสองแอ็ตทริบิวต์เอาต์พุต (คอขวดหลักใน GS) และอยู่ใกล้กับ "no-op" ไม่เช่นนั้นในทั้งสองขั้นตอน
  • ผูกพื้นผิวบัฟเฟอร์ที่มีสำหรับตัวละครแต่ละตัวในแบบอักษรตำแหน่งจุดสุดยอดของรูปสี่เหลี่ยมพื้นผิวที่สัมพันธ์กับจุดฐาน ข้อมูลนี้สามารถบีบอัดได้ 4 ตัวเลขต่อหนึ่งสี่เหลี่ยมโดยจัดเก็บเฉพาะออฟเซ็ตของจุดสุดยอดด้านซ้ายล่างและเข้ารหัสความกว้างและความสูงของกล่องที่จัดแนวแกน แบบอักษร 256 ตัวอักษรทั่วไปสามารถประกอบเข้ากับแคช L1 2kiB ได้)
  • ตั้งค่าเครื่องแบบสำหรับพื้นฐาน
  • ผูกเนื้อบัฟเฟอร์ด้วยการชดเชยแนวนอน เหล่านี้อาจอาจจะได้รับการคำนวณบน GPU แต่มันเป็นเรื่องง่ายและมีประสิทธิภาพมากขึ้นกับชนิดของสิ่งบน CPU ที่เป็นมันคือการดำเนินการตามลำดับอย่างเคร่งครัดและไม่ได้ทั้งหมดที่น่ารำคาญ (คิดว่าการจัดช่องไฟ) นอกจากนี้มันจะต้องผ่านการตอบรับอีกซึ่งจะเป็นจุดซิงค์อีก
  • ทำให้ข้อมูลที่สร้างไว้ก่อนหน้านี้จากบัฟเฟอร์ความคิดเห็นเวอร์เท็กซ์ shader ดึงออฟเซ็ตแนวนอนของจุดฐานและออฟเซ็ตของจุดยอดมุมจากวัตถุบัฟเฟอร์ (โดยใช้ id ดั้งเดิมและดัชนีอักขระ) ID จุดยอดดั้งเดิมของจุดยอดที่ส่งมาคือ "รหัสดั้งเดิม" ของเรา (โปรดจำไว้ว่า GS เปลี่ยนจุดยอดให้เป็นสี่คน)

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

อย่างไรก็ตามแม้จะสมมติว่าลดลง 75% - เนื่องจากข้อมูลจุดสุดยอดที่จะแสดงจำนวนข้อความที่ "สมเหตุสมผล" นั้นอยู่ที่ประมาณ 50-100kiB เท่านั้น (ซึ่งเป็นศูนย์จริงสำหรับ GPU หรือ PCIe bus) - ฉันยังสงสัยว่าความซับซ้อนที่เพิ่มขึ้นและการสูญเสียความสามารถในการใช้งานร่วมกันได้นั้นคุ้มค่ากับปัญหา การลดศูนย์ลง 75% ยังคงเป็นศูนย์เท่านั้น ฉันยอมรับว่าไม่ได้ลองวิธีการข้างต้นและจำเป็นต้องมีการวิจัยเพิ่มเติมเพื่อสร้างข้อความรับรองที่มีคุณภาพอย่างแท้จริง แต่ถึงกระนั้นถ้าไม่มีใครสามารถแสดงให้เห็นถึงความแตกต่างของประสิทธิภาพที่น่าทึ่งอย่างแท้จริง (โดยใช้จำนวนข้อความ "ปกติ" ไม่ใช่ตัวอักษรนับพันล้าน!) มุมมองของฉันยังคงอยู่ที่ข้อมูลจุดสุดยอด ได้รับการพิจารณาเป็นส่วนหนึ่งของ "วิธีการแก้ปัญหาที่ทันสมัย" เรียบง่ายและตรงไปตรงมาใช้งานได้และทำงานได้ดี

เมื่ออ้างอิงถึง " OpenGL Insights " ข้างต้นแล้วมันก็คุ้มค่าที่จะชี้ให้เห็นบท"2D Shape Rendering by Distance Fields"โดย Stefan Gustavson ซึ่งจะอธิบายการเรนเดอร์ระยะทางอย่างละเอียด

อัปเดตปี 2559:

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

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

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

สุดท้ายการจัดเก็บเส้นโค้ง bezier ที่เกิดขึ้นจริงในการสร้างตัวละครและการประเมินพวกเขาในส่วนที่แตกได้กลายเป็นจริงที่มีประสิทธิภาพการทำงานที่ด้อยกว่าเล็กน้อย (แต่ไม่มากว่ามันเป็นปัญหา) และผลลัพธ์ที่น่าทึ่งแม้กำลังขยายสูงสุด
WebGL สาธิตการแสดงผลในรูปแบบ PDF ขนาดใหญ่ที่มีเทคนิคนี้ในเวลาจริงที่มีอยู่ที่นี่


1
พวกเขาดูค่อนข้างดี (แม้จะมีตัวกรองที่ไร้เดียงสาและไม่มีการแม็พเนื่องจากคุณมีพื้นผิวที่มีขนาดเล็กมากและข้อมูลก็แทรกเข้ามาได้อย่างดี) โดยส่วนตัวแล้วฉันคิดว่าพวกเขาดูดีกว่าเรื่อง "ของจริง" ในหลาย ๆ กรณีเพราะไม่มีสิ่งแปลกประหลาดที่บอกใบ้ซึ่งมักจะผลิตสิ่งที่ฉันเห็นว่าเป็น "แปลก" ตัวอย่างเช่นข้อความที่เล็กกว่านั้นไม่ได้รับความกล้าหาญอย่างกะทันหันโดยไม่มีเหตุผลที่ชัดเจนและไม่มีขอบเขตป๊อปต่อพิกเซล - เอฟเฟกต์ที่คุณมักเห็นด้วยแบบอักษร "ของจริง" อาจมีเหตุผลทางประวัติศาสตร์สำหรับสิ่งนั้น (1985 b / w แสดง) แต่วันนี้มันเกินความเข้าใจของฉันทำไมมันต้องเป็นเช่นนั้น
Damon

2
ใช้งานได้ & ดูดีมากขอบคุณสำหรับการแบ่งปัน! สำหรับผู้ที่ต้องการแหล่ง Shader HLSL frag ดูที่นี่ คุณสามารถปรับใช้สิ่งนี้สำหรับ GLSL ได้โดยแทนที่clip(...)บรรทัดด้วยif (text.a < 0.5) {discard;}(หรือtext.a < threshold) HTH
วิศวกร

1
ขอบคุณสำหรับการอัพเดท. ฉันหวังว่าฉันจะโหวตได้อีกครั้ง
Ben Voigt

2
@NicolBolas: ดูเหมือนว่าคุณจะไม่ได้อ่านอย่างระมัดระวัง คำถามทั้งสองอธิบายในคำตอบ เคปเลอร์ได้รับเป็นตัวอย่าง "รุ่นล่าสุด" ไม่มีการส่งครั้งที่สอง (และอธิบายว่าทำไม) และฉันระบุว่าฉันไม่เชื่อว่าเทคนิคการประหยัดแบนด์วิดธ์ที่เห็นได้ชัดนั้นเร็วกว่าหรือคุ้มค่ากับปัญหาเลย อย่างไรก็ตามความเชื่อหมายถึงไม่มีอะไรเลยเราต้องพยายามรู้ (ฉันไม่ได้เนื่องจากฉันไม่ได้พิจารณาการวาดข้อความจำนวน "ปกติ" เป็นปัญหาคอขวดในทางใดทางหนึ่ง) มันอาจจะคุ้มค่าในเมื่อใครจะหมดหวังกับแบนด์วิดธ์และมีข้อความ "ผิดปกติ" จำนวน
Damon

3
@NicolBolas: คุณพูดถูกต้องขอโทษนะ มันทำให้เข้าใจผิดเล็กน้อย ในย่อหน้าก่อนหน้าฉันเขียนว่า"อาจสร้างสิ่งนี้บน GPU ได้ แต่นั่นต้องได้รับการตอบรับและ ... isnogud" - แต่ก็ยังคง errornously กับ"ข้อมูลที่สร้างจากบัฟเฟอร์ความคิดเห็น" ฉันจะแก้ไขสิ่งนี้ อันที่จริงฉันจะเขียนสิ่งที่สมบูรณ์ในช่วงสุดสัปดาห์จึงไม่ชัดเจน
Damon

15

http://code.google.com/p/glyphy/

ความแตกต่างที่สำคัญระหว่าง GLyphy และตัวแสดง OpenGL อื่น ๆ ที่ใช้ SDF คือโครงการอื่น ๆ ส่วนใหญ่จะตัวอย่าง SDF ลงในพื้นผิว นี่เป็นปัญหาปกติทั้งหมดที่การสุ่มตัวอย่างมี กล่าวคือ มันบิดเบือนร่างและมีคุณภาพต่ำ GLyphy แทน SDF โดยใช้เวกเตอร์จริงที่ส่งไปยัง GPU ส่งผลให้มีการเรนเดอร์คุณภาพสูงมาก

ข้อเสียคือรหัสสำหรับ iOS ที่มี OpenGL ES ฉันอาจจะสร้างพอร์ต Windows / Linux OpenGL 4.x (หวังว่าผู้เขียนจะเพิ่มเอกสารจริงบางอย่าง)


3
ใครก็ตามที่สนใจใน GLyphy ควรดูคำพูดของผู้เขียนที่ Linux.conf.au 2014: youtube.com/watch?v=KdNxR5V7prk
Fizz

14

เทคนิคที่แพร่หลายที่สุดยังคงเป็นพื้นผิวล่าม อย่างไรก็ตามในปี 2005 LORIA ได้พัฒนาสิ่งที่เรียกว่า vector textures เช่นการเรนเดอร์กราฟิกแบบเวกเตอร์เป็น textures บน primitives หากมีสิ่งนี้ใช้ในการแปลงแบบอักษร TrueType หรือ OpenType เป็นพื้นผิวแบบเวกเตอร์คุณจะได้รับสิ่งนี้:

http://alice.loria.fr/index.php/publications.html?Paper=VTM@2005


2
คุณรู้จักการใช้งานโดยใช้เทคนิคนี้หรือไม่?
ลูกา

2
ไม่ (เหมือนในเกรดการผลิต) แต่กระดาษของ Kilgard (ดูคำตอบของฉันด้านล่างสำหรับลิงก์) มีบทวิจารณ์สั้น ๆ ซึ่งฉันสรุปว่า: ยังใช้งานไม่ได้ มีการวิจัยเพิ่มเติมในพื้นที่; ผลงานล่าสุดที่อ้างถึงโดย Kilgard รวมถึงresearch.microsoft.com/en-us/um/people/hoppe/ravg.pdfและuwspace.uwaterloo.ca/handle/10012/4262
Fizz

9

ฉันประหลาดใจที่ลูกของ Mark Kilgard, NV_path_rendering (NVpr) ไม่ได้กล่าวถึงข้างต้น แม้ว่าเป้าหมายจะกว้างกว่าการแสดงแบบอักษร แต่ก็สามารถแสดงข้อความจากแบบอักษรและการจัดช่องไฟ มันไม่จำเป็นต้องมีแม้แต่ OpenGL 4.1 แต่มันเป็นส่วนเสริมของผู้ขาย / Nvidia-only ในขณะนี้ โดยทั่วไปจะเปลี่ยนฟอนต์เป็นพา ธ ที่ใช้glPathGlyphsNVซึ่งขึ้นอยู่กับไลบรารีของ freetype2 เพื่อรับglGetPathSpacingNVเมทริกซ์ ฯลฯ จากนั้นคุณสามารถเข้าถึงข้อมูลการจัดช่องไฟด้วยและใช้กลไกการแสดงผลพา ธ ทั่วไปของ NVpr เพื่อแสดงข้อความจากการใช้ฟอนต์ (ฉันใส่ไว้ในเครื่องหมายคำพูดเนื่องจากไม่มีการแปลงที่แท้จริงเส้นโค้งจึงถูกนำมาใช้อย่างที่เป็นอยู่)

สาธิตบันทึกสำหรับความสามารถของตัวอักษร NVPRเป็นที่น่าเสียดายไม่น่าประทับใจโดยเฉพาะอย่างยิ่ง (อาจจะมีใครบางคนควรสร้างหนึ่งในตัวอย่างของSDF snazzier ที่ใคร ๆ ก็สามารถหาได้จากใน intertubes ... )

2011 NVPR API นำเสนอพูดคุยสำหรับส่วนแบบอักษรเริ่มต้นที่นี่และยังคงอยู่ในส่วนถัดไป ; มันค่อนข้างโชคร้ายที่วิธีการแยกงานนำเสนอนั้นเป็นอย่างไร

วัสดุทั่วไปเพิ่มเติมเกี่ยวกับ NVpr:

  • Nvidia NVpr ฮับแต่เนื้อหาบางอย่างในหน้า Landing Page ไม่ได้เป็นข้อมูลล่าสุด
  • Siggraph 2012 กระดาษสำหรับสมองของวิธีการแสดงผลเส้นทางที่เรียกว่า "stencil, cover" (StC); กระดาษยังอธิบายสั้น ๆ ว่าเทคโนโลยีการแข่งขันเช่น Direct2D ทำงานอย่างไร บิตตัวอักษรที่เกี่ยวข้องกับการได้รับการผลักไสให้ภาคผนวกของกระดาษที่ นอกจากนี้ยังมีความพิเศษบางอย่างเช่นวิดีโอ / สาธิต
  • งานนำเสนอ GTC 2014สำหรับสถานะการอัพเดท; สั้น: ตอนนี้ได้รับการสนับสนุนโดย Google ของ Skia (Nvidia สนับสนุนรหัสในช่วงปลายปี 2013 และ 2014) ซึ่งจะใช้ใน Google Chrome และ [เป็นอิสระจาก Skia ฉันคิดว่า] ในเบต้าของ Adobe Illustrator CC 2014
  • เอกสารอย่างเป็นทางการในรีจีสตรีส่วนขยายของ OpenGL
  • USPTO ได้รับอย่างน้อยสี่สิทธิบัตรเพื่อ Kilgard / Nvidia ในการเชื่อมต่อกับ NVPR ซึ่งคุณอาจจะต้องตระหนักถึงในกรณีที่คุณต้องการที่จะใช้เอสทีซีด้วยตัวเอง: US8698837 , US8698808 , US8704830และUS8730253 โปรดทราบว่ามีบางสิ่งที่เหมือนกับเอกสาร USPTO อีก 17 ฉบับที่เชื่อมต่อกับสิ่งนี้ในชื่อ "ตีพิมพ์เป็น" ซึ่งส่วนใหญ่เป็นแอปพลิเคชันสิทธิบัตร

และเนื่องจากคำว่า "stencil" ไม่ได้สร้างความนิยมใด ๆ ในหน้านี้ก่อนที่คำตอบของฉันจะปรากฏส่วนย่อยของชุมชน SO ที่เข้าร่วมในหน้านี้ตราบเท่าที่แม้จะเป็นจำนวนมากสวยก็ไม่รู้ tessellation ฟรี stencil-buffer- วิธีการพื้นฐานสำหรับการแสดงผลเส้นทาง / แบบอักษรโดยทั่วไป Kilgard มีการโพสต์คล้ายคำถามที่พบบ่อยที่ฟอรั่ม openglซึ่งอาจให้ความสว่างว่าวิธีการเรนเดอร์แบบไม่มีเส้นทาง tessellation แตกต่างจากกราฟิก 3D bog มาตรฐานแม้ว่าพวกเขาจะยังคงใช้ [GP] GPU (NVpr ต้องการชิปที่รองรับ CUDA)

สำหรับมุมมองทางประวัติศาสตร์ Kilgard ยังเป็นผู้ประพันธ์คลาสสิก"Simple OpenGL-based API สำหรับ Texture Mapped Text", SGI, 1997ซึ่งไม่ควรสับสนกับ NVpr ที่ใช้ลายฉลุซึ่งเปิดตัวในปี 2011


ส่วนใหญ่หากไม่ใช่วิธีล่าสุดทั้งหมดที่กล่าวถึงในหน้านี้รวมถึงวิธีที่ใช้ stencil เช่น NVpr หรือวิธี SDF เช่น GLyphy (ซึ่งฉันไม่ได้พูดถึงที่นี่อีกต่อไปเพราะคำตอบอื่น ๆ ครอบคลุมอยู่แล้ว) มีข้อ จำกัด เพียงข้อเดียว: เหมาะสำหรับการแสดงข้อความขนาดใหญ่บนจอภาพธรรมดา (~ 100 DPI) โดยไม่ต้องมีการสั่นไหวที่ระดับใด ๆ และพวกเขายังดูดีแม้ในขนาดที่เล็กบนหน้าจอที่มีความละเอียดสูงเช่น DPI พวกเขาไม่ได้ให้สิ่งที่ Direct2D + DirectWrite ของ Microsoft มอบให้คุณอย่างเต็มที่นั่นคือการพูดถึงร่ายมนตร์เล็ก ๆ บนหน้าจอหลัก (สำหรับการสำรวจด้วยภาพของการบอกเป็นนัยโดยทั่วไปดูหน้า typotheque นี้ทรัพยากรในเชิงลึกเพิ่มเติมอยู่ใน antigrain.com )

ฉันไม่ได้ตระหนักถึงสิ่งที่ใช้ OpenGL และแบบเปิดซึ่งสามารถทำสิ่งที่ Microsoft สามารถทำได้ในขณะนี้ (ฉันยอมรับความไม่รู้ของ Apple OS X GL / Quartz internals เนื่องจากความรู้ที่ดีที่สุดของฉัน Apple ยังไม่ได้เผยแพร่วิธีที่พวกเขาทำสิ่งที่ใช้ตัวอักษร / เส้นทางการแสดงผลตาม GL ดูเหมือนว่า OS X ซึ่งแตกต่างจาก MacOS 9 ไม่ ซึ่งทำให้บางคนรำคาญ ) อย่างไรก็ตามมีรายงานการวิจัยปี 2556 ฉบับหนึ่งที่กล่าวถึงนัยผ่าน OpenGL shaders ที่เขียนโดย Nicolas P. Rougier ของ INRIA; มันอาจจะคุ้มค่าที่จะอ่านถ้าคุณต้องการพูดเป็นนัยจาก OpenGL ในขณะที่อาจดูเหมือนว่าห้องสมุดอย่าง freetype ได้ทำทุกอย่างแล้วเมื่อมันบอกใบ้ แต่นั่นก็ไม่จริงด้วยเหตุผลดังต่อไปนี้ซึ่งฉันอ้างอิงจากกระดาษ:

ไลบรารี FreeType สามารถ rasterize glyph โดยใช้ sub-pixel anti-aliasing ในโหมด RGB อย่างไรก็ตามนี่เป็นเพียงครึ่งหนึ่งของปัญหาเนื่องจากเราต้องการบรรลุการวางตำแหน่งพิกเซลย่อยเพื่อให้ได้ตำแหน่งที่แม่นยำของร่ายมนตร์ การแสดงรูปสี่เหลี่ยมพื้นผิวที่พิกัดพิกเซลแบบเศษส่วนไม่สามารถแก้ปัญหาได้เนื่องจากจะส่งผลเฉพาะการแก้ไขพื้นผิวที่ระดับพิกเซลทั้งหมด แต่เราต้องการบรรลุการเปลี่ยนแปลงที่แม่นยำ (ระหว่าง 0 และ 1) ในโดเมนย่อย สามารถทำได้ในส่วนที่แตก [... ]

การแก้ปัญหาไม่ใช่เรื่องเล็กน้อยดังนั้นฉันจะไม่พยายามอธิบายที่นี่ (กระดาษเป็นแบบเปิดโล่ง)


อีกสิ่งหนึ่งที่ฉันได้เรียนรู้จากกระดาษของ Rougier (ซึ่ง Kilgard ไม่ได้พิจารณา) ก็คือพลังของตัวอักษร (Microsoft + Adobe) ไม่ได้สร้างวิธีการกำหนดช่องไฟแบบหนึ่ง แต่สองวิธี อันเก่านั้นขึ้นอยู่กับโต๊ะที่เรียกว่าเคอร์และสนับสนุนโดยประเภทฟรี ใหม่นี้เรียกว่า GPOS และรองรับเฉพาะฟอนต์ไลบรารีที่ใหม่กว่าเช่น HarfBuzz หรือ pango ในโลกซอฟต์แวร์เสรี เนื่องจาก NVpr ดูเหมือนจะไม่สนับสนุนทั้งสองไลบรารีเหล่านั้นการจัดช่องไฟอาจไม่ทำงานนอกกรอบด้วย NVpr สำหรับแบบอักษรใหม่บางตัว มีบางคนที่เห็นได้ชัดในป่าตามการอภิปรายฟอรั่มนี้

ท้ายที่สุดถ้าคุณต้องทำเค้าโครงข้อความที่ซับซ้อน (CTL)คุณดูเหมือนจะโชคไม่ดีกับ OpenGL เนื่องจากไม่มีไลบรารีที่ใช้ OpenGL ปรากฏอยู่ในนั้น (DirectWrite ในอีกทางหนึ่งสามารถจัดการ CTL ได้) มีไลบรารีแบบโอเพ่นซอร์สเช่น HarfBuzz ซึ่งสามารถสร้าง CTL ได้ แต่ฉันไม่รู้ว่าคุณจะทำให้พวกมันทำงานได้ดีอย่างไร (เช่นเดียวกับการใช้วิธี stencil-based) ผ่านทาง OpenGL คุณอาจต้องเขียนรหัสกาวเพื่อแยกเค้าร่างที่มีรูปร่างใหม่และป้อนเข้าสู่โซลูชั่นที่อิง NVpr หรือ SDF เป็นเส้นทาง


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

1
ฉันเห็นด้วยกับสิ่งนั้นบ้าง วิธีการของตัวเอง ("stencil, cover") นั้นไม่ใช่เรื่องยากที่จะนำไปใช้โดยตรงใน OpenGL แต่มันจะมีค่าใช้จ่ายสูงหากใช้วิธีนี้อย่างไร้เดียงสา Skia [ผ่าน Ganesh] ลองใช้วิธีการแก้ปัญหาลายฉลุที่จุด แต่ให้ขึ้นกับมันตาม Kilgrad วิธีการใช้งานของ Nvidia ซึ่งเป็นเลเยอร์ด้านล่างโดยใช้ความสามารถของ CUDA ทำให้มันทำงานได้ คุณสามารถลอง "Mantle" StC ด้วยตัวคุณเองโดยใช้ทั้งนามสกุล EXT / ARB แต่ระวังว่า Kilgard / Nvidia มีการยื่นขอจดสิทธิบัตรสองรายการใน NVpr
Fizz

3

ฉันคิดว่าทางออกที่ดีที่สุดของคุณคือดูกราฟิกของ cairoด้วย OpenGL แบ็กเอนด์

ปัญหาเดียวที่ฉันมีเมื่อพัฒนาต้นแบบที่มีแกน 3.3 คือเลิกใช้ฟังก์ชั่นในแบ็กเอนด์ OpenGL เมื่อ 1-2 ปีก่อนสถานการณ์อาจจะดีขึ้น ...

อย่างไรก็ตามฉันหวังว่าในอนาคตไดรเวอร์กราฟิก opengl บนเดสก์ท็อปจะใช้ OpenVG

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