พื้นผิวประสานงานไม่ต่อเนื่องกับ mipmaps สร้างตะเข็บ


9

ฉันเพิ่งเริ่มเรียนรู้ openGL และฉันได้สิ่งประดิษฐ์นี้เมื่อสร้างพื้นผิวด้วย mipmaps โดยทั่วไปเมื่อชิ้นส่วนตัวอย่างขอบของพื้นผิวของฉันมันตรวจพบความไม่ต่อเนื่อง (พูดจาก 1 ถึง 0) และเลือก mipmap ที่เล็กที่สุดซึ่งสร้างรอยต่อที่น่าเกลียดนี้:

ตะเข็บที่น่าเกลียด http://cdn.imghack.se/images/6bbe0ad0173cac003cd5dddc94bd43c7.png

ดังนั้นฉันจึงพยายามแทนที่ gradients ด้วยตนเองโดยใช้ textureGrad:

//fragVert is the original vertex from the vertex shader
vec2 ll = vec2((atan(fragVert.y, fragVert.x) / 3.1415926 + 1.0) * 0.5, (asin(fragVert.z) / 3.1415926 + 0.5));
vec2 ll2 = ll;
if (ll.x < 0.01 || ll.x > 0.99)
    ll2.x = .5;
vec4 surfaceColor = textureGrad(material.tex, ll, dFdx(ll2), dFdy(ll2));

ตอนนี้ฉันได้รับสองตะเข็บแทนที่จะเป็นหนึ่ง ฉันจะกำจัดพวกเขาได้อย่างไร และทำไมรหัสด้านบนจึงสร้าง 2 ตะเข็บ

2 eams http://cdn.imghack.se/images/44a38ef13cc2cdd801967c9223fdd2d3.png

คุณไม่สามารถบอกได้จากภาพสองภาพ แต่ตะเข็บทั้งสองอยู่ที่ด้านใดด้านหนึ่งของรอยตะเข็บเดิม


2
ทรงกลมของคุณเป็นตาข่ายหรือคุณ raytracing ทรงกลมวิเคราะห์ใน Shader หรือเช่นนั้น? หากเป็นตาข่ายคนมักจะแก้ปัญหานี้โดยการทำซ้ำจุดตามแนวตะเข็บเพื่อให้ verts ด้านหนึ่งสามารถมี u = 0 และด้านอื่นมี u = 1
Nathan Reed

สำหรับสาเหตุที่รหัสของคุณสร้างสองตะเข็บฉันคาดว่าเป็นเพราะมันสร้างสองความไม่ต่อเนื่อง - ที่ที่คุณกระโดดจาก 0.01 ถึง 0.5 และอีกที่ที่คุณกระโดดจาก 0.99 ถึง 0.5 มันเป็นปัญหาเดียวกับเมื่อคุณกระโดดจาก 0 ถึง 1 - ไม่ใช่การกระโดดครั้งใหญ่ แต่ยังเป็นการกระโดดครั้งใหญ่
Nathan Reed

ฉันมีตาข่ายสำหรับทรงกลม มันเป็นเดวาไดเรนดังนั้นจุดยอดไม่เข้าแถวกับตะเข็บ สิ่งที่ตลกเกี่ยวกับตะเข็บทั้งสองคือรอยตะเข็บเดิมหายไป นอกจากนี้ฉันยังได้ตะเข็บ 2 อันเหมือนกันแม้ว่าฉันจะหนีบที่. 01 หรือ. 99
omikun

คุณสามารถโพสต์ภาพหน้าจอของเคสสองตะเข็บได้หรือไม่? และคุณสร้าง UV ได้อย่างไร (คุณสามารถโพสต์ส่วนที่เกี่ยวข้องในรหัสของคุณได้อย่างไร) ฉันคิดว่าคุณกำลังสร้างพวกเขาแบบขั้นตอนใน shader ไม่ใช่แค่ interpolating พวกเขาจากจุดยอดอื่น ๆ ตาข่าย dodecahedron ของคุณจะไม่ทำงานเลย
นาธานรีด

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

คำตอบ:


4

ตามรหัส shader ที่คุณโพสต์คุณไม่ได้สอดแทรก UVs จากจุดยอด แต่ดูเหมือนว่าคุณกำลังแก้ไขตำแหน่ง 3D (fragVert ) แล้วคำนวณยูวีด้วยการเปลี่ยนเป็นรูปทรงกลมพิกัด

การวิเคราะห์ของคุณถูกต้องเนื่องจากมีการเลือก mipmap ที่เล็กที่สุดเมื่อมีความไม่ต่อเนื่องเนื่องจากการเลือก mipmap นั้นขึ้นอยู่กับอนุพันธ์ที่ประเมินตัวเลขจาก UV ที่ใช้ในพิกเซลข้างเคียง เมื่อหนึ่งพิกเซลมี u = 0 และอื่น ๆ มี u = 1 คุณจะได้อนุพันธ์ที่ใหญ่มาก การพยายามแก้ไขของคุณมีปัญหาเดียวกันในอนุพันธ์ที่มีขนาดใหญ่เกิดขึ้นรอบ u = 0.01 และ u = 0.99 ซึ่งเป็นสาเหตุที่ตะเข็บสองอันปรากฏที่ด้านใดด้านหนึ่งของรอยต่อเดิม

วิธีการที่ค่อนข้างง่ายในการแก้ไขปัญหาคือการตัดสินใจว่าระดับ mip ใดที่จะใช้ด้วยตัวคุณเองและโทรหา textureLodตัวอย่างโดยตรง หากดาวเคราะห์นั้นอยู่ใกล้กับกล้องเสมอคุณสามารถกำหนดระดับ mip ให้เป็น 0 ได้ยาก (หรือสำหรับเรื่องนั้นอย่ารวมระดับ mip ไว้ในพื้นผิวเลย) มิฉะนั้นอาจขึ้นอยู่กับ log2 ของระยะทางของจุดจากกล้องโดยปรับขนาดตามปัจจัยที่เหมาะสม โปรดทราบว่าสิ่งนี้จะปิดการใช้งานการกรอง anisotropic อย่างมีประสิทธิภาพ

แนวทางที่ถูกต้องมากขึ้นคือการคำนวณอนุพันธ์ที่มีคุณภาพสูงกว่า แทนที่จะใช้dFdxและdFdyใน UVS ซึ่งมีต่อเนื่องเนื่องจากการที่atan2คุณสามารถนำไปใช้dFdxและdFdyการfragVert(ซึ่งจะมีอย่างต่อเนื่องทุกทางรอบทรงกลม) จากนั้นใช้แคลคูลัส (กฎโซ่) ในการหาสูตรที่จะได้รับสัญญาซื้อขายล่วงหน้ายูวี จากฐานะสัญญาซื้อขายล่วงหน้า สิ่งนี้จะซับซ้อนและช้าลง แต่มีข้อได้เปรียบที่การกรองแบบ Anisotropic ควรทำงาน

ในที่สุดเนื่องจากคุณเพิ่งเริ่มใช้งาน OpenGL ฉันจะทราบว่าในขณะที่การคำนวณ UV จากพิกัดทรงกลมเป็นวิธีที่ถูกต้องสมบูรณ์ในการสร้างรูปทรงกลมแบบทรงกลมมันไม่ใช่วิธี "ปกติ" ที่คนส่วนใหญ่เลือก มันเป็นเรื่องธรรมดามากที่จะสร้างตาข่ายทรงกลมที่มีรังสียูวีระบุต่อจุดยอดและผ่านจากจุดยอดไปยังจุดภาพพิกเซล (สอดแทรกเชิงเส้นตรงข้ามในแต่ละสามเหลี่ยม) จุดยอดจะถูกวางตามแนวรอยต่อเช่นนี้ซึ่งมีสองจุดของแต่ละจุดยอดในตำแหน่งเดียวกัน แต่ครึ่งหนึ่งกับ u = 0 เชื่อมต่อกับรูปสามเหลี่ยมด้านหนึ่งและอีกครึ่งหนึ่งที่เชื่อมต่อกับ u = 1 สามเหลี่ยมที่อยู่อีกด้านหนึ่ง วิธีนี้จะช่วยลดรอยตะเข็บที่มองเห็นได้และไม่จำเป็นต้องใช้ลูกเล่นในการปรับพิกเซล

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