2012-07-01 7 views
6

मैं ग्राफिक्स इंजन के रूप में Ogre3D का उपयोग कर रहा हूं।क्या मैं इस सीजी कार्यक्रम के साथ कुछ गलत कर रहा हूं?

मैं एक जाल मैन्युअल जो ठीक काम करता है बनाने के लिए, uvs सही हैं और ग्रिड निर्देशांक प्रतिनिधित्व करने के लिए सेट कर रहे हैं (इस उदाहरण के लिए ग्रिड है एक 10 x 10)

मैं शिखर कार्यक्रम में कुछ भी नहीं है और एक बहुत है सरल टुकड़ा कार्यक्रम। मैंने व्याख्या करने के लिए दोनों कार्यक्रमों और भौतिक फ़ाइल को शामिल किया है।

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

मैंने बाईं ओर आउटपुट का एक स्क्रीनशॉट और दाईं ओर मूल छवि भी शामिल की है। टुकड़ा शेडर भी शीर्ष पर एक साधारण ग्रिड खींचता है ताकि मैं सुनिश्चित कर सकूं कि यूवी समन्वय सही ढंग से पारित किए जा रहे थे। जो वे प्रतीत होते हैं।

enter image description here

किसी भी अंतर्दृष्टि बहुत सराहना की जाएगी के रूप में मैं वास्तव में अनिश्चित क्या im गलत कर रहा हूँ।

सामग्री फ़ाइल:

// CG Vertex shader definition 
vertex_program PlainTexture_VS cg    
{ 
    // Look in this source file for shader code 
    source GameObjStandard.cg 
    // Use this function for the vertex shader    
    entry_point main_plain_texture_vp  
    // Compile the shader to vs_1_1 format  
    profiles arbvp1  

    // This block saves us from manually setting parameters in code 
    default_params      
    { 
     // Ogre will put the worldviewproj into our 'worldViewProj' parameter for us. 
     param_named_auto worldViewProj worldviewproj_matrix   
     // Note that 'worldViewProj' is a parameter in the cg code. 
    } 
} 

// CG Pixel shader definition 
fragment_program PlainTexture_PS cg    
{ 
    // Look in this source file for shader code 
    source GameObjStandard.cg   
    // Use this function for the pixel shader  
    entry_point main_plain_texture_fp  
    // Compile to ps_1_1 format  
    profiles arbfp1    
} 

material PlainTexture 
{ 
    // Material has one technique 
    technique     
    { 
     // This technique has one pass 
     pass     
     { 
      // Make this pass use the vertex shader defined above 
      vertex_program_ref PlainTexture_VS  
      { 
      } 
      // Make this pass use the pixel shader defined above 
      fragment_program_ref PlainTexture_PS  
      { 
      } 
      texture_unit 0 
      { 
       filtering none 
       // This pass will use this 2D texture as its input 
       texture test.png 2d   
      } 
      texture_unit 1 
      { 
       texture textureatlas.png 2d 
       tex_address_mode clamp 
       filtering none 
      } 
     } 
    } 
} 

तटरक्षक फ़ाइल:

void main_plain_texture_vp(
    // Vertex Inputs 
    float4 position  : POSITION, // Vertex position in model space 
    float2 texCoord0 : TEXCOORD0, // Texture UV set 0 

    // Outputs 
    out float4 oPosition : POSITION, // Transformed vertex position 
    out float2 uv0  : TEXCOORD0, // UV0 

    // Model Level Inputs 
    uniform float4x4 worldViewProj) 
{ 
    // Calculate output position 
    oPosition = mul(worldViewProj, position); 

    // Simply copy the input vertex UV to the output 
    uv0 = texCoord0; 
} 

void main_plain_texture_fp(
    // Pixel Inputs 
    float2 uv0  : TEXCOORD0, // UV interpolated for current pixel 

    // Outputs 
    out float4 color : COLOR, // Output color we want to write 

    // Model Level Inputs 
    uniform sampler2D Tex0: TEXUNIT0, 

uniform sampler2D Tex1: TEXUNIT1)  // Texture we're going to use 
{ 

//get the index position by truncating the uv coordinates 
float2 flooredIndexes = floor(uv0); 

if((uv0.x > 0.9 && uv0.x < 1.1) 
|| (uv0.x > 1.9 && uv0.x < 2.1) 
|| (uv0.x > 2.9 && uv0.x < 3.1) 
|| (uv0.x > 3.9 && uv0.x < 4.1) 
|| (uv0.x > 4.9 && uv0.x < 5.1) 
|| (uv0.x > 5.9 && uv0.x < 6.1) 
|| (uv0.x > 6.9 && uv0.x < 7.1) 
|| (uv0.x > 7.9 && uv0.x < 8.1) 
|| (uv0.x > 8.9 && uv0.x < 9.1)) { 
    float4 color1 = {1.0,0,0,0}; 
    color = color1; 
} else if((uv0.y > 0.9 && uv0.y < 1.1) 
|| (uv0.y > 1.9 && uv0.y < 2.1) 
|| (uv0.y > 2.9 && uv0.y < 3.1) 
|| (uv0.y > 3.9 && uv0.y < 4.1) 
|| (uv0.y > 4.9 && uv0.y < 5.1) 
|| (uv0.y > 5.9 && uv0.y < 6.1) 
|| (uv0.y > 6.9 && uv0.y < 7.1) 
|| (uv0.y > 7.9 && uv0.y < 8.1) 
|| (uv0.y > 8.9 && uv0.y < 9.1)) { 
    float4 color1 = {1.0,0,0,0}; 
    color = color1; 
} else { 
    //get the colour of the index texture Tex0 at this floored coordinate 
    float4 indexColour = tex2D(Tex0, (1.0/10)*flooredIndexes); 
    color = indexColour; 
} 
} 
+0

संपादन के लिए धन्यवाद, मुझे यकीन है कि कैसे में :) –

+0

बदलते छवियों डाल करने के लिए 'Float4 indexColour = tex2D (Tex0, (1.0/10) * flooredIndexes) नहीं था float4 indexColour = tex2D (Tex0, (1.0/20) * फर्श इंडेक्स); समस्या को हल कर सकते हैं – hamed

+0

सुनिश्चित नहीं है कि इससे मदद मिली या नहीं, इसने समस्या को हल नहीं किया। 1/10 वीं से गुणा करने का कारण यह है कि यूवी 0 में इंडेक्स वर्तमान में यू और वी दोनों दिशाओं में 0 - 10 से चलते हैं। मैं इस मान को फर्श करता हूं क्योंकि यह खंड कार्यक्रम में अंतरित होता है, इसलिए मुझे 5.6 जैसे मान मिलते हैं, अगर मैं इस मान को फर्श करता हूं तो मुझे 5 मिलते हैं जो टाइल्स चौड़ाई (10) की संख्या से विभाजित होते हैं, मुझे यूवी समन्वय की आवश्यकता होती है, मुझे 0.5 –

उत्तर

6

ठीक है इसलिए इसकी एक समय हो गया जब से मैं अपने समस्याओं दुर्भाग्य से ऑनलाइन नहीं किया गया तो आशा का हल मिल गया यह इसी तरह के मुद्दों के साथ किसी में मदद करता है ।

जब किसी भी बनावट आप हमेशा बनावट texels 2^n * 2^m जहां मीटर और n चौड़ाई और बनावट की ऊंचाई रहे हैं में एक आकार बनाना चाहिए बनाने। यह मेरी पहली गलती थी हालांकि मुझे उस समय इसका एहसास नहीं हुआ था।

कारण मैंने इसे नहीं देखा था क्योंकि मेरा मुख्य बनावट एटलस इस सिद्धांत पर आधारित था और 1024 x 1024 बनावट थी। जो मैंने ध्यान में नहीं लिया था वह बनावट का आकार था जिसे मैंने बनावट बनाम बना दिया था। चूंकि मेरा नक्शा 10 x 10 था, मैं इंडेक्स के लिए 10 x 10 बनावट बना रहा था, यह मुझे लगता था कि फिर किसी भी तरह से फैलाया जा रहा है (यह सुनिश्चित नहीं है कि यह बैकएंड में कैसे काम करता है) या तो 16 x 16 या 8 x 8 हो, एक साथ texels के रूप में यह किया था।

पहली बात जिसने मुझे सुराग दिया था, जब मैंने फ़ोटोशॉप में अपने कैनवास को स्केल किया और पाया कि मिश्रित रंग जो मैं बना रहा था, वही था जो मैं अपने ogre3d आउटपुट पर प्राप्त कर रहा था।

वैसे भी पर चलती ..

एक बार मैं इस पता लगा था मैं भर में के रूप में

//Create index material 
Ogre::TexturePtr indexTexture = Ogre::TextureManager::getSingleton().createManual("indexTexture","General",Ogre::TextureType::TEX_TYPE_2D, 16, 16, 0, Ogre::PixelFormat::PF_BYTE_BGRA, Ogre::TU_DEFAULT); 

Ogre::HardwarePixelBufferSharedPtr pixelBuffer = indexTexture->getBuffer(); 
pixelBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL); 

const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock(); 
Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data); 

Ogre::uint8 counter = 0; 
for (size_t j = 0; j < 16; j++) { 
for(size_t i = 0; i < 16; i++) 
{  
     if(i==8 || i==7) { 
    *pDest++ = 3; // B 
    *pDest++ = 0; // G 
    *pDest++ = 0; // R 
    *pDest++ = 0; // A 
    } else { 
    *pDest++ = 1; // B 
    *pDest++ = 0; // G 
    *pDest++ = 0; // R 
    *pDest++ = 0; // A 
    } 
    counter++; 
} 
} 

pixelBuffer->unlock(); 

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

अब भर में मैं सही तकनीक के लिए इसे पारित और मेरी सामग्री में पारित करने के लिए किया था इस बनावट पारित करने के लिए, यह किया गया था:

Ogre::MaterialPtr material = Ogre::MaterialPtr(Ogre::MaterialManager::getSingleton().getByName("PlainTexture")); 
float mapSize = 16; 
float tas = 2; 
material->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("mapSize",mapSize); 
material->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("tas",tas); 
material->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName("indexTexture");  

यह दो मानों भी गुजरता है, mapSize आकार जा रहा है नक्शा स्वयं ही टाइल्स में (इसे एक वर्ग मानते हुए) और tas बनावट एटलस आकार (एटलस की चौड़ाई में विभिन्न बनावट वर्गों की संख्या) होने के कारण।

अनुमति देने के लिए मेरी सामग्री को समझने के लिए मैं सिर्फ क्या पारित कर में मैं इस प्रकार मेरी सामग्री फ़ाइल में थोड़ा सा संशोधन करने की जरूरत:

// CG Pixel shader definition 
fragment_program PlainTexture_PS cg    
{ 
    source GameObjStandard.cg  
    entry_point main_plain_texture_fp 
    profiles arbfp1 
default_params 
{ 
    param_named tas float 
    param_named 
}    
} 

और मेरे पास थोड़ा नए सिरे से परिभाषित किया गया था भी

pass     
{ 
        // Make this pass use the vertex shader defined above 
    vertex_program_ref PlainTexture_VS  
    { 
    } 
        // Make this pass use the pixel shader defined above 
    fragment_program_ref PlainTexture_PS  
    { 
    } 
    texture_unit 0 
    { 
     filtering none   
    } 
texture_unit 1 
{ 
    texture textureatlas.png 2d 
    tex_address_mode clamp 
    filtering anisotropic 
} 
} 

मैं तो दुबारा लिखा मेरे द्वारा किए गए परिवर्तनों को ध्यान में रखकर सीजी बनावट खंड कार्यक्रम।

void main_plain_texture_fp(
    float2 uv0 : TEXCOORD0, // UV interpolated for current pixel 
    out float4 color : COLOR, // Output color we want to write 
uniform float tas, 
uniform float mapSize, 

    // Model Level Inputs 
    uniform sampler2D Tex0: TEXUNIT0, 
uniform sampler2D Tex1: TEXUNIT1) 
{ 
//get the index position by truncating the uv coordinates 
float2 flooredIndexes = floor(uv0); 

//get the colour of the index texture Tex0 at this floored coordinate 
float4 indexColour = tex2D(Tex0, ((1.0/mapSize) * flooredIndexes)+(0.5/mapSize)); 

//calculate the uv offset required for texture atlas range = 0 - 255 
float indexValue = (255 * indexColour.b) + (255 * indexColour.g) + (255 * indexColour.r); 

//float indexValue = (tas * tas) - indexValue0; 

if(indexValue < tas*tas) { 
    float row = floor(indexValue/tas); 
    float col = frac(indexValue/tas) * tas; 

    float uvFraction = 1.0/tas; 

    float uBase = col * uvFraction; 
    float vBase = 1 - ((tas - row) * uvFraction); 

    float uOffset = frac(uv0.x)/tas; 
    float vOffset = (frac(uv0.y))/tas; 

    float uNew = uBase + uOffset; 
    float vNew = vBase + vOffset; 

    float2 uvNew = {uNew, vNew}; 

    if(frac(uv0.x) > 0.99 || frac(uv0.x) < 0.01) { 
    float4 color1 = {1,1,1,0}; 
    color = (0.2*color1) + (0.8*tex2D(Tex1,uvNew)); 
    } else if(frac(uv0.y) > 0.99 || frac(uv0.y) < 0.01) { 
    float4 color1 = {1,1,1,0}; 
    color = (0.2*color1) + (0.8*tex2D(Tex1,uvNew)); 
    } else { 
    color = tex2D(Tex1,uvNew); 
    } 


} else { 
    float4 color2 = {0.0,0,0,0}; 
    color = color2; 
} 
} 

यह बनावट एटलस से आवश्यक सही Texel की गणना करता है, यह भी 80% Texel रंग और 20% सफेद संयोजन से शीर्ष पर एक बेहोश ग्रिड overlays।

हैं बनावट एटलस रंग सूचकांक बनावट द्वारा निर्दिष्ट के सूचकांक नहीं है तो यह सिर्फ काले आउटपुट (यह मुख्य रूप से इसलिए इसकी बहुत पहचानना आसान है।

नीचे एक का उपयोग कर उत्पादन का एक उदाहरण है । `` करने के लिए; 2 एक्स 2 बनावट एटलस

enter image description here

+0

@TheSHEEEP आशा है कि यह आपकी मदद करता है/आपकी रूचि रखता है। –

+0

निश्चित रूप से सहायक, धन्यवाद :) – TheSHEEEP

+0

@TheSHEEEP कोई समस्या नहीं है, अगर आप सोच रहे हैं, तो मैं नीचे दिए गए प्रस्तुत छवि का उल्लेख करना भूल गया हूं, जो वास्तव में ऊपर दिए गए कोड के साथ नहीं मिलता है। उपरोक्त कोड ऊपर एक सफेद अर्द्ध पारदर्शी ग्रिड रखता है, छवि ग्रिड के नीचे बनावट को ध्यान में रखती है और केवल काले रंग का चित्रण करती है। –

संबंधित मुद्दे