1 คะแนน โดย GN⁺ 2024-11-11 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • การเรนเดอร์ข้อความโดยไม่ใช้เท็กซ์เจอร์

    • โดยทั่วไป หากต้องการเรนเดอร์ข้อความ จะต้องเรนเดอร์ glyph ทั้งหมดของฟอนต์ลงใน atlas ก่อน จากนั้น bind เป็นเท็กซ์เจอร์ แล้วค่อยวาดสามเหลี่ยมบนหน้าจอเพื่อเรนเดอร์ glyph ทีละตัว
    • แนะนำวิธีแบบง่ายสำหรับแสดงข้อความดีบักอย่างรวดเร็ว
    • อธิบายเทคนิคที่สามารถวาดข้อความทั้งหมดได้ด้วย draw call เพียงครั้งเดียว
  • ฟอนต์: พิกเซลที่ไม่ใช้เท็กซ์เจอร์

    • เพื่อตัดการใช้ฟอนต์ atlas texture ออกไป จำเป็นต้องเก็บสิ่งที่คล้ายกับ font atlas ไว้ภายใน fragment shader
    • สามารถใช้ค่าคงที่จำนวนเต็มเพื่อเก็บบิตแมป และใช้สิ่งนี้ในการเรนเดอร์ glyph ได้
    • สามารถใช้จำนวนเต็ม 8 บิตเป็นบิตแมปเพื่อวาดลงบนหน้าจอใน GLSL fragment shader ได้
  • draw call เดียว

    • สามารถใช้ instance draw call เพื่อหลีกเลี่ยงคำสั่งวาดที่ซ้ำๆ ได้
    • ใช้ข้อมูลที่ประกอบด้วย position offset และข้อความที่จะส่งออกสำหรับแต่ละอินสแตนซ์
    • แบ่งข้อความออกเป็น 4 ตัวอักษรแล้วแปลงเป็น uint32_t เพื่อเก็บไว้ในโครงสร้าง word_data
  • Vertex Shader

    • Vertex shader สร้างเอาต์พุต 3 อย่าง
    • วางจุดยอดของสามเหลี่ยมลงบนหน้าจอผ่าน gl_Position
    • ส่งคำที่จะเรนเดอร์ต่อไปยัง fragment shader
    • สร้าง texture coordinate เพื่อคำนวณพิกัด uv
  • Fragment Shader

    • Fragment shader ต้องการข้อมูล 3 อย่างเพื่อเรนเดอร์ข้อความ
    • เรนเดอร์ glyph โดยแมปพิกัด uv ไปยังบิตที่ถูกต้องของ glyph bitmap
    • หากบิตถูกตั้งค่าไว้ให้เรนเดอร์ด้วยสี foreground และหากไม่ได้ตั้งค่าให้เรนเดอร์ด้วยสี background
  • การติดตั้งใช้งานทั้งหมดและซอร์สโค้ด

    • สามารถดูการติดตั้งใช้งานของเทคนิคนี้ได้จากซอร์สโค้ดของโมดูล le_print_debug_print_text
    • โมดูลนี้ช่วยให้สามารถแสดงข้อความดีบักบนหน้าจอได้อย่างง่ายดาย

1 ความคิดเห็น

 
GN⁺ 2024-11-11
ความคิดเห็นจาก Hacker News
  • การเขียนโค้ดด้วยเลขคณิตง่าย ๆ บน ShaderToy เป็นงานที่ทั้งสนุกและทำได้ไม่ยาก มีตัวอย่างการดัดแปลงข้อความหลายแบบ
    • ตัวอย่าง: Matrix ที่มีน้อยกว่า 300 อักขระ, เอฟเฟกต์หน้าจอ CRT สีเขียว เป็นต้น
  • วิธีนี้สร้างสรรค์ดี แต่ผลลัพธ์ไม่ได้สวยงามนัก ถ้าต้องการผลลัพธ์ที่ดีกว่านี้ก็สามารถเพิ่มบิตได้มากขึ้น แต่แนวทางที่มีประสิทธิภาพกว่าคือใช้พิกเซลขาวดำแล้วเก็บเป็นเท็กซ์เจอร์
  • วิธีทั่วไปในการวาดข้อความในเอนจินเรนเดอร์ 3D สมัยใหม่คือใช้ข้อความแบบ SDF ซึ่งจะสร้างแอตลาสของ signed distance field โดยใช้ texture atlas แบบดั้งเดิม
  • ไม่เคยลองทำอัลกอริทึมเรนเดอร์ข้อความด้วยตัวเองโดยตรง แต่เคยมีประสบการณ์ในการทำหลายแบบ เนื่องจากต้องการความเป็นอิสระจากความละเอียดและ anti-aliasing วิธีนี้จึงไม่ได้ช่วยนัก
  • วิธีนี้มีแนวคิดคล้ายกับวิธีของ Will Dobbie แต่เรียบง่ายกว่า โดยเป็นการเก็บข้อมูลพิกเซลไว้ในอาร์เรย์
  • ยังมีตัวเลือกในการเรนเดอร์ข้อความเป็นเมชด้วย โดย TextMeshPro ใช้ signed distance field เพื่อรองรับการสเกลได้ตามต้องการ
  • คงน่าสนุกถ้าได้ลองเทียบประสิทธิภาพกับวิธีใช้เท็กซ์เจอร์แบบดั้งเดิม สำหรับงานง่าย ๆ บน GPU สมัยใหม่ มีโอกาสสูงที่คำตอบด้านประสิทธิภาพจะเป็น "ได้"
  • วิดีโอของ Sebastian Lague พูดถึงเทคนิคการเรนเดอร์ฟอนต์หลายแบบ
  • เคยใช้เทคนิคคล้ายกันที่ฝังข้อมูลฟอนต์ไว้ในซอร์สโค้ดของ fragment shader แล้วใช้ snprintf ส่งออกตรงไปยัง GPU buffer
  • วิธีนี้คล้ายกับการวาดสไปรต์เล็ก ๆ ขนาด 8x8 ใน BBC Basic ทำให้นึกถึงความทรงจำเมื่อ 35 ปีก่อน
  • GPU มีประสิทธิภาพในการเรนเดอร์จากเท็กซ์เจอร์ แต่ค่อนข้างช้ากว่าเมื่อเป็นการจัดการบิต แม้จะประหยัดหน่วยความจำ แต่ก็ยังสงสัยว่าเร็วกว่าการใช้แอตลาสจริงหรือไม่
  • มีคำถามว่าการอัปโหลดเท็กซ์เจอร์ขนาดเล็กไปยัง GPU ส่งผลต่อประสิทธิภาพมากแค่ไหน และสงสัยว่าสามารถเรนเดอร์สตริงลงบนเท็กซ์เจอร์แบบ 2D แล้วแสดงเท็กซ์เจอร์นั้นบนสามเหลี่ยมสองอันได้หรือไม่