การทำแผนที่ UV โดยทั่วไปคือสิ่งที่เรียกว่าเปลี่ยนแปลงเลียนแบบ นั่นหมายถึงการแมปของสามเหลี่ยมแต่ละอันระหว่างพื้นที่ 3D กับพื้นที่พื้นผิวสามารถรวมถึงการหมุนการแปลการปรับ / สควอชและความลาดเอียง (เช่นอะไรก็ตามที่เราสามารถทำได้ด้วยการคูณเมทริกซ์เอกพันธ์)
สิ่งที่เกี่ยวกับการแปลงเลียนแบบคือพวกมันเหมือนกันทั่วทั้งโดเมน - การหมุนการแปลมาตราส่วนและความเบ้ที่เราใช้กับพื้นผิวที่อยู่ใกล้จุดสุดยอด A เหมือนกับสิ่งที่เราใช้ใกล้จุดยอด B ภายในสามเหลี่ยมใด ๆ เส้นที่ขนานกันในพื้นที่หนึ่งจะถูกแมปกับเส้นคู่ขนานในอีกช่องหนึ่งโดยไม่ต้องมาบรรจบกัน
แต่การเรียวแบบค่อยเป็นค่อยไปที่คุณพยายามจะใช้นั้นไม่เหมือนกัน - มันเป็นการจับคู่เส้นขนานในพื้นผิวเป็นการบรรจบเส้นบนตาข่าย นั่นหมายถึงขนาดของพื้นผิวที่วัดได้ทั่วทั้งวงนั้นมีการเปลี่ยนแปลงอย่างต่อเนื่องเมื่อเราเลื่อนแถบลง นั่นเป็นมากกว่าการแปลงเลียนแบบของการทำแผนที่ UV แบบ 2 มิติที่สามารถนำเสนอได้อย่างถูกต้อง: การประมาณค่าพิกัดยูวี 2 มิติระหว่างจุดยอดที่อยู่ติดกันจะได้สเกลที่สม่ำเสมอหนึ่งตลอดทั้งขอบแม้กระทั่งเส้นทแยงมุม ความไม่ตรงกันนั้นเป็นสิ่งที่สร้างซิกแซกที่กระจัดกระจาย
ปัญหานี้เกิดขึ้นเมื่อใดก็ตามที่เราต้องการแมปสี่เหลี่ยมกับสี่เหลี่ยมคางหมู - ด้านขนานกับการบรรจบกัน: ไม่มีการแปลงเลียนแบบที่ทำเช่นนี้ดังนั้นเราต้องประมาณมันทีละส่วนเพื่อนำไปสู่ตะเข็บที่มองเห็นได้
เพื่อวัตถุประสงค์ส่วนใหญ่คุณสามารถลดผลกระทบได้โดยการเพิ่มรูปทรงเรขาคณิตเพิ่มเติม การเพิ่มจำนวนเขตการปกครองตามความยาวของแถบและแยกแถบออกเป็นสองส่วนหรือมากกว่าตามความกว้างโดยมีเส้นทแยงมุมของรูปสามเหลี่ยมที่จัดในรูปแบบรูปแฉกแนวตั้งสามารถทำให้เอฟเฟ็กต์น้อยลง มันจะถูกนำเสนอในระดับหนึ่งเสมอตราบใดที่เราใช้การแปลงเลียนแบบ
แต่มีวิธีการอยู่รอบ ๆ เราสามารถใช้กลอุบายแบบเดียวกันกับที่เราใช้สำหรับการเรนเดอร์ 3D เพื่อวาดสี่เหลี่ยมคางหมูในมุมมองของผนังและพื้นรูปสี่เหลี่ยมผืนผ้า: เราใช้พิกัด projective !
เลียนแบบพื้นผิว:
พื้นผิว Projective:
ในการทำเช่นนี้เราต้องเพิ่มพิกัดยูวีตัวที่สาม (uvw) และแก้ไขเฉดสีของเรา
เมื่อพิจารณาจากสเกลปัจจัยในแต่ละจุด (พูดเท่ากับความกว้างของแถบของคุณ ณ จุดนั้น) คุณสามารถสร้างพิกัดยูวีโปรเจ็กต์สามมิติจากพิกัดยูวี 2D ปกติของคุณด้วยวิธีนี้:
Vector3 uv3 = ((Vector3)uv2) * scale;
uv3.z = scale;
ในการใช้พิกัด uvw 3D เหล่านี้กับตาข่ายของคุณคุณจะต้องใช้ Vector3 เกินพิกัด Mesh.SetUVs (ช่องสัญญาณภายในรายการ uvs)
และให้แน่ใจว่าได้เปลี่ยนโครงสร้างอินพุตของ shader เพื่อคาดหวังพิกัดพื้นผิว 3 มิติ (แสดงไว้ที่นี่โดยใช้ shader ที่ไม่มีแสงสว่างดีฟอลต์)
struct appdata
{
float4 vertex : POSITION;
float3 uv : TEXCOORD0; // Change float2 to float 3.
};
// Also do this for the uv sent from the vertex shader to the fragment shader.
คุณจะต้องตัดมาโคร TRANSFORM_TEX ออกใน shader ที่จุดยอดเนื่องจากคาดว่าจะเป็น 2D uv:
// o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.uv = v.uv;
// If you define a float4 with the special name _MainTex_ST,
// you can get the same effect the macro had by doing this:
o.uv.xy = o.uv.xy * _MainTex_ST.xy + _MainTex_ST.zw;
ในที่สุดเมื่อต้องการกลับไปที่พิกัดพื้นผิว 2D สำหรับการสุ่มตัวอย่างพื้นผิวคุณเพียงแค่หารด้วยพิกัดที่สามในส่วนของส่วนย่อยของคุณ:
float2 uv = i.uv.xy / i.uv.z;
เนื่องจากเราได้สร้างพิกัดยูวี 3 มิติจากพิกัด 2D ที่เราต้องการโดยการคูณด้วยจำนวนเดียวกันการดำเนินการทั้งสองจึงยกเลิกและเรากลับไปที่พิกัด 2D ดั้งเดิมที่เราต้องการ แต่ตอนนี้มีการแก้ไขเชิงเส้นตรงระหว่างจุดยอด : D
เป็นสิ่งสำคัญที่จะทำหารนี้ต่อชิ้นส่วนและไม่ได้อยู่ในส่วนยอด หากทำต่อจุดสุดยอดแล้วเราจะกลับไปแก้ไขพิกัดที่เป็นเส้นตรงตามแนวขอบแต่ละเส้นและเราสูญเสียความไม่เชิงเส้นที่เราพยายามแนะนำกับพิกัดเชิง Projective!
id
และcount
? อะไรUVs.ToArray()
ทำอย่างไร คุณกำลังอัปโหลดจุดยอดและพิกัดพื้นผิวไปยังการ์ดได้อย่างไร