เป็นไปได้หรือไม่ที่จะทราบว่ามีชิ้นส่วนกี่ชิ้นที่ทำผ่านการทดสอบลายฉลุ?


11

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

ฉันรู้ว่ามีแนวคิดที่คล้ายกันสำหรับวิทยาการปล่อยออกมาจากรูปทรงเรขาคณิต Shader ที่เรียกว่าเปลี่ยนข้อเสนอแนะ ฉันต้องการทราบว่ามีแนวคิดแบบเดียวกันนี้สำหรับการทดสอบเศษและการทดสอบลายฉลุหรือไม่


วิธีแก้ปัญหาที่หยาบก็คือการวาดสีที่ตัดกันอีกสีหนึ่งผ่านลายฉลุบันทึกบัฟเฟอร์นั้นและนับจำนวนพิกเซลที่เปลี่ยนแปลง
TheBuzzSaw

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

@ChristianRau ดูเหมือนว่าจะมีการนับเฉพาะชิ้นส่วนที่ผ่านการทดสอบเชิงลึกเท่านั้น แต่จะไม่สนใจการทดสอบการใช้ลายฉลุการละทิ้งและการทดสอบอัลฟา
Maurice Laveaux

2
@ChristianRau และ Maurice สเปคARB_occlusion_queryดั้งเดิมบอกอย่างชัดเจนว่ามันนับตัวอย่างที่ผ่านการทดสอบทั้งความลึกและการทดสอบลายฉลุ ดูเพิ่มเติมคำถามนี้ StackOverflow
นาธานรีด

@NathanReed ดูเหมือนว่าคุณกำลังจะเขียนคำตอบ
คริสพูดว่า Reinstate Monica

คำตอบ:


10

แนวทางที่เป็นไปได้วิธีหนึ่งอาจเป็นการใช้ Hardware Occlusion Query

คุณสามารถใช้ข้อเท็จจริงที่กำหนดรายละเอียดการทดสอบฉลุจะดำเนินการก่อนการทดสอบความลึกและมีเพียงเศษเล็กเศษน้อยที่ผ่านการทดสอบความลึกเท่านั้นที่จะถูกนับโดย Occlusion Query

ตัวอย่างง่ายๆ (ไม่ได้ทดสอบ) จะเป็นเช่น:

    GLuint samples_query = 0;
    GLuint samples_passed = 0;
    glGenQueries(1, &samples_query);
    // Initialize your buffers and textures ...
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_STENCIL_TEST);

    // Set up the values on the stencil buffer ...

    // Now we count the fragments that pass the stencil test
    glDepthFunc(GL_ALWAYS); // Set up the depth test to always pass
    glBeginQuery(GL_SAMPLES_PASSED, samples_query);
    // Render your meshes here
    glEndQuery(GL_SAMPLES_PASSED);
    glGetQueryObjectuiv(samples_query, GL_QUERY_RESULT, &samples_passed);
    // samples_passed holds the number of fragments that passed the stencil test (if any)

    // Release your resources ...
    glDeleteQueries(1, &samples_query);

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

    GLuint query_done = 0;
    glGetQueryObjectuiv(samples_query, GL_QUERY_RESULT_AVAILABLE, &query_done);
    if (query_done != 0)
        // Your query result is ready
    else
        // Maybe check the next frame?

2

หากสิ่งที่คุณสนใจคือพื้นที่คุณสามารถลดขนาดของ stencil buffer ได้จนกว่าจะถึงหนึ่งพิกเซลและอนุมานพื้นที่นั้นจากสีของมัน

ขั้นตอนจะเป็น:

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