TL; DR: 2 * 1LSB รูปสามเหลี่ยมที่ pdf แตกหักในหน่วย edgecase ที่ 0 และ 1 เนื่องจากการหนีบ วิธีการแก้ปัญหาคือการ lerp เพื่อ 1 บิตสม่ำเสมอ dither ใน edgecases เหล่านั้น
ฉันกำลังเพิ่มคำตอบที่สองโดยเห็นว่านี่เป็นเรื่องที่ซับซ้อนกว่าที่ฉันคิดไว้เล็กน้อย ดูเหมือนว่าปัญหานี้เป็น "สิ่งที่ต้องทำ: จำเป็นต้องบีบหรือไม่" ในรหัสของฉันตั้งแต่ฉันเปลี่ยนจาก normalized เป็นรูปสามเหลี่ยม dithering ... ในปี 2012 รู้สึกดีที่ได้มองในที่สุด :) รหัสเต็มสำหรับการแก้ปัญหา / ภาพที่ใช้ตลอดการโพสต์: https://www.shadertoy.com/view/llXfzS
ก่อนอื่นนี่คือปัญหาที่เรากำลังดูเมื่อทำการหาปริมาณสัญญาณถึง 3 บิตด้วย 2 * 1LSB รูปสามเหลี่ยม pdf pdf:
- สิ่งที่ hotmultimedia แสดงให้เห็น
การเพิ่มความคมชัดผลที่อธิบายไว้ในคำถามชัดเจนขึ้น: ผลลัพธ์ไม่ได้เฉลี่ยกับสีดำ / ขาวใน edgecases (และจริง ๆ แล้วขยายเกิน 0/1 ก่อนที่จะทำเช่นนั้น)
การดูกราฟจะให้ข้อมูลเชิงลึกมากขึ้น:
(เส้นสีเทาทำเครื่องหมาย 0/1, สีเทายังเป็นสัญญาณที่เรากำลังพยายามเอาท์พุท, เส้นสีเหลืองคือค่าเฉลี่ยของเอาท์พุท dithered / quantized, สีแดงเป็นข้อผิดพลาด (สัญญาณเฉลี่ย))
ที่น่าสนใจไม่เพียง แต่ผลผลิตเฉลี่ยไม่ใช่ 0/1 ที่ขีด จำกัด แต่ก็ไม่เชิงเส้น เมื่อมองที่ปลายล่างมันทำให้เข้าใจได้ง่ายว่าทำไม diverges เอาท์พุท: เมื่อสัญญาณ dithered เริ่มรวมค่าลบ clamping-on-output จะเปลี่ยนค่าของส่วน dithered ด้านล่างของเอาต์พุต (เช่นค่าลบ) ดังนั้น การเพิ่มมูลค่าของค่าเฉลี่ย ภาพประกอบดูเหมือนจะอยู่ในลำดับ (ชุดรูปแบบสมมาตร 2LSB dither ค่าเฉลี่ยยังคงเป็นสีเหลือง):
ทีนี้ถ้าเราใช้ 1LSB normalized dither ไม่มีปัญหาในกรณีขอบเลย แต่แน่นอนว่าเราสูญเสียคุณสมบัติที่ดีของการทำสีสามเหลี่ยม (ดูตัวอย่างงานนำเสนอนี้ )
วิธีแก้ปัญหา (ในทางปฏิบัติเชิงประจักษ์) (แฮ็ค) คือเปลี่ยนกลับเป็น [-0.5; 0.5 [การทำให้เหมือนกันอย่างสิ้นเชิงสำหรับ edgecase:
float dithertri = (rnd.x + rnd.y - 1.0); //note: symmetric, triangular dither, [-1;1[
float dithernorm = rnd.x - 0.5; //note: symmetric, uniform dither [-0.5;0.5[
float sizt_lo = clamp( v/(0.5/7.0), 0.0, 1.0 );
float sizt_hi = 1.0 - clamp( (v-6.5/7.0)/(1.0-6.5/7.0), 0.0, 1.0 );
dither = lerp( dithernorm, dithertri, min(sizt_lo, sizt_hi) );
ซึ่งแก้ไข edgecases ในขณะที่รักษารูปสามเหลี่ยมที่ยังคงสภาพเหมือนเดิมไว้สำหรับช่วงที่เหลืออยู่:
ดังนั้นเพื่อที่จะไม่ตอบคำถามของคุณ: ฉันไม่รู้ว่ามีวิธีแก้ปัญหาทางคณิตศาสตร์ที่ดีกว่านี้หรือไม่และกระตือรือร้นที่จะรู้ว่า Masters of Past ได้ทำอะไรไปบ้าง :) อย่างน้อยเราก็มีแฮ็คที่น่ากลัวนี้
แก้ไข
ฉันควรจะครอบคลุมข้อเสนอแนะการแก้ปัญหาที่กำหนดในคำถามเพียงแค่บีบอัดสัญญาณ เนื่องจากค่าเฉลี่ยไม่เชิงเส้นใน edgecases เพียงการบีบอัดสัญญาณอินพุตจึงไม่ให้ผลลัพธ์ที่สมบูรณ์แบบ - แม้ว่าจะแก้ไขจุดสิ้นสุด:
อ้างอิง