2012-03-01 14 views
12

में किसी क्षेत्र में बनावट को मैप करने पर सीम समस्या जब मैं ओपनजीएल में पृथ्वी का प्रतिनिधित्व करने के लिए ज्यामिति बनाने की कोशिश कर रहा हूं। मेरे पास क्षेत्रफल कम या कम है (हालांकि अंडाकार भूगर्भ के करीब पृथ्वी है)। मैं पृथ्वी की सतह के एक बनावट को मानचित्रित करता हूं (शायद यह एक मर्केटर प्रक्षेपण या कुछ समान है)। बनावट के यूवी निर्देशांक ज्यामिति अक्षांश और देशांतर से मेल खाते हैं। मेरे पास दो मुद्दे हैं जिन्हें मैं हल करने में असमर्थ हूं। मैं ओपनसेनग्राफ का उपयोग कर रहा हूं लेकिन मुझे लगता है कि यह एक सामान्य ओपनजीएल/3 डी प्रोग्रामिंग प्रश्न है।ओपनजीएल

  • एक बनावट सीम है जो बहुत स्पष्ट है। मुझे यकीन है कि ऐसा इसलिए होता है क्योंकि मुझे पता नहीं है कि यूवी समन्वय को एक्सवाईजेड में कैसे मैप करना है जहां सीम होता है। मैं केवल चारों ओर लपेटकर से पहले अंतिम शीर्ष बिंदु अप करने के लिए यूवी coords नक्शा ... आप दो अलग अलग यूवी ही XYZ शीर्ष करने के लिए निर्देशांक सीवन खत्म करने के लिए मैप करने की आवश्यकता होगी। क्या इसके आसपास जाने के लिए आमतौर पर इस्तेमाल की जाने वाली चाल है, या क्या मैं इसे गलत कर रहा हूं?

  • ध्रुवों पर पागल घुमावदार विरूपण चल रहा है। मैं (दक्षिण ध्रुव के लिए [0.5,0] पृथ्वी के लिए, मैं उत्तरी ध्रुव के लिए उपयोग [0.5,1], और) क्योंकि मैं ध्रुवों पर एक भी यूवी बिंदु नक्शा इस अनुमान लगा रहा हूँ। यद्यपि आप और क्या करेंगे? मैं इसके साथ रहने का सॉर्ट कर सकता हूं ... लेकिन यह कम रिज़ॉल्यूशन मेस पर बेहद ध्यान देने योग्य है।

मैंने यह दिखाने के लिए एक छवि संलग्न की है कि मैं किस बारे में बात कर रहा हूं।

I suck at rendering Earth

+2

आप साझा कर सकते हैं कि कैसे आप यूवी निर्देशांक पैदा कर रहे हैं, और क्या विधि आप वस्तु संरचना करने के लिए प्रयोग कर रहे हैं? –

+0

जेनेरिक OpenGL ES कैसे संस्करण के लिए: http://stackoverflow.com/questions/322111/any-one-know-of-an-opengl-es-example-of-an-interactive-globe-earth-for-the- iphon संबंधित समस्या: http://stackoverflow.com/questions/17488259/opengl-mapping-texture-to-sphere –

उत्तर

6

सामान्य तरीके से नियंत्रित किया जाता है इस एक घन नक्शा, नहीं एक 2 डी बनावट के प्रयोग से है।

हालांकि, यदि आप 2 डी बनावट का उपयोग करने पर जोर देते हैं, तो आपको अपने जाल के टोपोलॉजी में ब्रेक बनाना होगा। कारण आप अनुदैर्ध्य लाइन है कि क्योंकि आप एक बनावट के साथ एक शीर्ष 0.9 या तो की तरह कुछ का समन्वय है मिलता है, और उसके पड़ोसी शिखर एक बनावट 0.0 का समन्वय है। आप वास्तव में क्या चाहते हैं कि 0.9 एक पड़ोसी एक 1.0 बनावट समन्वय है।

ऐसा करने का अर्थ क्षेत्र की एक पंक्ति के नीचे स्थिति को दोहराना है। तो आपके पास एक ही स्थिति है जो आपके डेटा में दो बार उपयोग की जाती है। एक 1.0 के बनावट समन्वय और पड़ोसियों के 0.9 के एक बनावट समन्वय से जुड़ा हुआ है। दूसरे में 0.0 का एक बनावट समन्वय है, और पड़ोसियों 0.1 के साथ एक चरम है।

विषयगत रूप से, आपको अपने क्षेत्र के नीचे एक अनुदैर्ध्य टुकड़ा लेने की आवश्यकता है।

+0

बेकार है। सर उठाने के लिए धन्यवाद। एक त्वरित अनुवर्ती के रूप में, किसी भी मौके पर आपके पास गोलाकारों के लिए घन मानचित्र लागू करने पर संसाधन हैं? – Prismatic

+0

@Pris: गोलाकारों के लिए क्यूबैप्स टियरिवियल हैं। आप क्यूबमैप में बनावट समन्वय के रूप में सीधे कशेरुक पदों (या मानक) का उपयोग कर सकते हैं। क्यूबमैप में घन में व्यवस्थित 6 क्वाड्रेट होते हैं। बनावट समन्वय घन के केंद्र से एक दिशा निर्धारित करता है, घन के साथ छेड़छाड़ स्वयं texel पैदा करता है। – datenwolf

2

आपका लिंक वास्तव में मुझे, बाहर की मदद की Furqan, धन्यवाद।
क्यों आप इसे समझ नहीं सकता है? एक बिंदु जहां मैंने ठोकर खाई थी, कि मुझे नहीं पता था कि बनावट निर्देशांक की गणना करते समय आप [0,1] अंतराल से अधिक हो सकते हैं। यही कारण है कि यह बहुत आसान ओपन सभी प्रक्षेप कर के साथ और सही स्थिति की गणना करने के जहां बनावट वास्तव में समाप्त हो जाती है बिना दूसरे से बनावट के एक पक्ष से कूदने के लिए बनाता है।

+0

यह बहुत उपयोगी है। धन्यवाद! वास्तव में सरल और सुरुचिपूर्ण समाधान! –

0

निकोल बोलास ने कहा, कुछ त्रिकोणों में यूवी निर्देशांक ~ 0.9 से 0 तक जा रहे हैं, इसलिए इंटरपोलेशन सीम के चारों ओर बनावट को गड़बड़ कर देता है। मेरे कोड में, मैंने इस फ़ंक्शन को सीम के चारों ओर के शीर्षकों को डुप्लिकेट करने के लिए बनाया है। यह उन चरमों को विभाजित करने वाली एक तेज रेखा बनाएगा। यदि आपके बनावट में केवल सीम (प्रशांत महासागर?) के आसपास पानी है, तो आप इस लाइन को नोटिस नहीं कर सकते हैं। आशा करता हूँ की ये काम करेगा।

/** 
* After spherical projection, some triangles have vertices with 
* UV coordinates that are far away (0 to 1), because the Azimuth 
* at 2*pi = 0. Interpolating between 0 to 1 creates artifacts 
* around that seam (the whole texture is thinly repeated at 
* the triangles around the seam). 
* This function duplicates vertices around the seam to avoid 
* these artifacts. 
*/ 
void PlatonicSolid::SubdivideAzimuthSeam() { 
    if (m_texCoord == NULL) { 
     ApplySphericalProjection(); 
    } 

    // to take note of the trianges in the seam 
    int facesSeam[m_numFaces]; 

    // check all triangles, looking for triangles with vertices 
    // separated ~2π. First count. 
    int nSeam = 0; 
    for (int i=0;i < m_numFaces; ++i) { 
     // check the 3 vertices of the triangle 
     int a = m_faces[3*i]; 
     int b = m_faces[3*i+1]; 
     int c = m_faces[3*i+2]; 
     // just check the seam in the azimuth 
     float ua = m_texCoord[2*a]; 
     float ub = m_texCoord[2*b]; 
     float uc = m_texCoord[2*c]; 
     if (fabsf(ua-ub)>0.5f || fabsf(ua-uc)>0.5f || fabsf(ub-uc)>0.5f) { 
      //test::printValue("Face: ", i, "\n"); 
      facesSeam[nSeam] = i; 
      ++nSeam; 
     } 
    } 

    if (nSeam==0) { 
     // no changes 
     return; 
    } 

    // reserve more memory 
    int nVertex = m_numVertices; 
    m_numVertices += nSeam; 
    m_vertices = (float*)realloc((void*)m_vertices, 3*m_numVertices*sizeof(float)); 
    m_texCoord = (float*)realloc((void*)m_texCoord, 2*m_numVertices*sizeof(float)); 

    // now duplicate vertices in the seam 
    // (the number of triangles/faces is the same) 
    for (int i=0; i < nSeam; ++i, ++nVertex) { 
     int t = facesSeam[i]; // triangle index 
     // check the 3 vertices of the triangle 
     int a = m_faces[3*t]; 
     int b = m_faces[3*t+1]; 
     int c = m_faces[3*t+2]; 
     // just check the seam in the azimuth 
     float u_ab = fabsf(m_texCoord[2*a] - m_texCoord[2*b]); 
     float u_ac = fabsf(m_texCoord[2*a] - m_texCoord[2*c]); 
     float u_bc = fabsf(m_texCoord[2*b] - m_texCoord[2*c]); 
     // select the vertex further away from the other 2 
     int f = 2; 
     if (u_ab >= 0.5f && u_ac >= 0.5f) { 
      c = a; 
      f = 0; 
     } else if (u_ab >= 0.5f && u_bc >= 0.5f) { 
      c = b; 
      f = 1; 
     } 

     m_vertices[3*nVertex] = m_vertices[3*c];  // x 
     m_vertices[3*nVertex+1] = m_vertices[3*c+1]; // y 
     m_vertices[3*nVertex+2] = m_vertices[3*c+2]; // z 
     // repeat u from texcoord 
     m_texCoord[2*nVertex] = 1.0f - m_texCoord[2*c]; 
     m_texCoord[2*nVertex+1] = m_texCoord[2*c+1]; 
     // change this face so all the vertices have close UV 
     m_faces[3*t+f] = nVertex; 
    } 

} 
0

तुम भी एक गंदा रास्ता तय कर सकते हैं: शिखर शेडर और टुकड़ा शेडर और पुनर्गणना सही बनावट टुकड़ा शेडर में समन्वय के बीच में अंतर्वेशन पहला, दूसरा पदों।यह कुछ हद तक धीमा हो सकता है, लेकिन इसमें डुप्लिकेट वर्टेक्स शामिल नहीं हैं और यह आसान है, मुझे लगता है।

उदाहरण के लिए:
शिखर शेडर:

#version 150 core 
uniform mat4 projM; 
uniform mat4 viewM; 
uniform mat4 modelM; 
in vec4 in_Position; 
in vec2 in_TextureCoord; 
out vec2 pass_TextureCoord; 
out vec2 pass_xy_position; 
void main(void) { 
    gl_Position = projM * viewM * modelM * in_Position; 
    pass_xy_position = in_Position.xy; // 2d spinning interpolates good! 
    pass_TextureCoord = in_TextureCoord; 
} 

टुकड़ा शेडर:

#version 150 core 
uniform sampler2D texture1; 
in vec2 pass_xy_position; 
in vec2 pass_TextureCoord; 
out vec4 out_Color; 

#define PI 3.141592653589793238462643383279 

void main(void) { 
    vec2 tc = pass_TextureCoord; 
    tc.x = (PI + atan(pass_xy_position.y, pass_xy_position.x))/(2 * PI); // calculate angle and map it to 0..1 
    out_Color = texture(texture1, tc); 
} 
1

यह एक लंबे समय के लिए इस अत्यंत कष्टप्रद मुद्दा यह पता लगाने की ले लिया। मैं एकता में सी # के साथ प्रोग्रामिंग कर रहा हूं और मैं किसी भी शिखर को डुप्लिकेट नहीं करना चाहता था। (मेरी अवधारणा के साथ भविष्य के मुद्दों का कारण बन जाएगा) तो मैं शेडर विचार के साथ गया और यह बहुत अच्छी तरह से काम करता है। हालांकि मुझे यकीन है कि कोड कुछ भारी कर्तव्य अनुकूलन का उपयोग कर सकता है, मुझे यह पता लगाना था कि इसे सीजी से कैसे बंद करना है, लेकिन यह काम करता है। अगर किसी और ने इस पोस्ट में भाग लिया है, जैसा कि मैंने किया था, वही समस्या का समाधान ढूंढ रहा है।

Shader "Custom/isoshader" { 
Properties { 
     decal ("Base (RGB)", 2D) = "white" {} 
    } 
    SubShader { 
     Pass { 
     Fog { Mode Off } 

     CGPROGRAM 

     #pragma vertex vert 
     #pragma fragment frag 
     #define PI 3.141592653589793238462643383279 

     sampler2D decal; 

     struct appdata { 
      float4 vertex : POSITION; 
      float4 texcoord : TEXCOORD0; 
     }; 

     struct v2f { 
      float4 pos : SV_POSITION; 
      float4 tex : TEXCOORD0; 
      float3 pass_xy_position : TEXCOORD1; 
     }; 

     v2f vert(appdata v){ 
      v2f o; 
      o.pos = mul(UNITY_MATRIX_MVP, v.vertex); 
      o.pass_xy_position = v.vertex.xyz; 
      o.tex = v.texcoord; 
      return o; 
     } 

     float4 frag(v2f i) : COLOR { 
      float3 tc = i.tex; 
      tc.x = (PI + atan2(i.pass_xy_position.x, i.pass_xy_position.z))/(2 * PI); 
      float4 color = tex2D(decal, tc); 
      return color; 
     } 

     ENDCG 
    } 
} 

}

+0

यदि आपके गोलाकार जाल 1 का व्यास नहीं है और 0,0,0 की उत्पत्ति है तो स्थिति की बजाय सामान्य का उपयोग करने का सुझाव दूंगा – jjxtra

0

एक दृष्टिकोण को स्वीकार कर लिया जवाब में की तरह है। कोड शिखर की सरणी पैदा करने में जिम्मेदार बताते हैं आप इस प्रकार का कोड होगा: आप त्रिकोण जो मध्याह्न गठबंधन आप भी glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); चाहते हैं नहीं हैं, तो

// FOR EVERY TRIANGLE 
const float threshold = 0.7; 
if(tcoords_1.s > threshold || tcoords_2.s > threshold || tcoords_3.s > threshold) 
{ 
    if(tcoords_1.s < 1. - threshold) 
    { 
     tcoords_1.s += 1.; 
    } 
    if(tcoords_2.s < 1. - threshold) 
    { 
     tcoords_2.s += 1.; 
    } 
    if(tcoords_3.s < 1. - threshold) 
    { 
     tcoords_3.s += 1.; 
    } 
} 

। तुम भी glDrawArrays का उपयोग करने के बाद से ही स्थिति के साथ कोने अलग संरचना coords होगा की जरूरत है।

मुझे लगता है कि जाने के लिए बेहतर तरीका सभी बुरी, जो इस मामले में बनावट coords प्रक्षेप है की जड़ को खत्म करने की है। चूंकि आप अपने क्षेत्र/दीर्घवृत्ताभ के बारे में मूल रूप से सभी जानते हैं, आप टुकड़ा स्थिति के आधार पर शेडर में बनावट coords, Normals, आदि की गणना कर सकते हैं। इसका मतलब है कि आपके सीपीयू कोड वर्टेक्स विशेषताओं को उत्पन्न करना बहुत आसान होगा और आप फिर से अनुक्रमित ड्राइंग का उपयोग कर सकते हैं। और मुझे नहीं लगता कि यह दृष्टिकोण गंदा है। यह साफ है।