2012-07-01 22 views
6

Tôi đang sử dụng Ogre3D làm công cụ đồ họa.Tôi có làm gì sai với chương trình CG này không?

tôi tạo ra một lưới bằng tay mà làm việc tốt, UVs là chính xác và được thiết lập để đại diện cho tọa độ lưới (ví dụ này lưới là 10 x 10)

tôi không làm gì trong chương trình đỉnh và có rất chương trình phân đoạn đơn giản. Tôi đã bao gồm cả hai chương trình cộng với tệp tài liệu để giải thích.

Vấn đề của tôi là ngay cả khi bộ lọc được đặt thành không màu nào dường như không giống như ảnh gốc của tôi (đây chỉ là hình ảnh thử nghiệm đang sử dụng vì tôi gặp sự cố khi tạo texture theo cách thủ công ogre). Nó chỉ ra rằng vấn đề không phải là mã của tôi trong ogre nhưng nhiều khả năng một cái gì đó để làm với một trong hai tập tin tài liệu hoặc các mảnh/đỉnh chương trình.

Tôi cũng đã bao gồm ảnh chụp màn hình của đầu ra ở bên trái và hình ảnh gốc ở bên phải. Trình đổ bóng phân mảnh cũng vẽ một lưới đơn giản trên đầu để tôi có thể đảm bảo rằng các tọa độ tia cực tím đã được truyền qua một cách chính xác. Chúng có vẻ như thế.

enter image description here

Bất kỳ cái nhìn sâu sắc sẽ được nhiều đánh giá cao như tôi thực sự không chắc chắn những gì im làm sai.

tập tin Chất liệu:

// 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 
      } 
     } 
    } 
} 

CG File:

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

Cảm ơn để chỉnh sửa, tôi wasnt chắc chắn làm thế nào để đưa hình ảnh trong :) –

+0

thay đổi 'float4 indexColour = tex2D (Tex0, (1.0/10) * flooredIndexes); 'cho' float4 indexColour = tex2D (Tex0, (1.0/20) * flooredIndexes); 'có thể giải quyết vấn đề – hamed

+0

Không chắc chắn nếu điều đó đã giúp hay không, nó không giải quyết được vấn đề. Lý do tôi nhân với 1/10 là vì các chỉ số trong uv0 hiện đang chạy từ 0 - 10 theo cả hướng u và v. Tôi sàn giá trị này vì nội suy của nó trong chương trình phân đoạn nên tôi nhận được các giá trị như 5.6, nếu tôi sàn giá trị này tôi nhận được 5 chia cho số chiều rộng của gạch (10) cho tôi tọa độ cực tím, 0,5 –

Trả lời

6

Ok vậy nó được một thời gian kể từ khi tôi tìm thấy giải pháp cho vấn đề của tôi tiếc là không được trực tuyến để hy vọng điều này sẽ giúp bất cứ ai có vấn đề tương tự .

Khi tạo ra bất kỳ kết cấu, bạn nên luôn luôn làm cho kết cấu một kích thước trong texels 2^n * 2^m nơi mn là chiều rộng và chiều cao của kết cấu. Đây là sai lầm đầu tiên của tôi mặc dù tôi đã không nhận ra nó vào thời điểm đó.

Lý do tôi không phát hiện ra điều này là do bản đồ kết cấu chính của tôi dựa trên nguyên tắc này và là kết cấu 1024 x 1024. Những gì tôi đã không đưa vào tài khoản là kích thước của kết cấu tôi đã tạo ra như là chỉ số kết cấu. Vì bản đồ của tôi là 10 x 10, tôi đã tạo một kết cấu 10 x 10 cho các chỉ mục, tôi đoán là sau đó được kéo dài bằng cách nào đó (không chắc chắn nó hoạt động như thế nào trong phần phụ trợ) hoặc là 16 x 16 hoặc 8 x 8, trộn texels với nhau như nó đã làm nó.

Điều đầu tiên mang lại cho tôi manh mối là khi tôi thu nhỏ canvas của mình trong photoshop và thấy rằng các màu pha trộn mà nó tạo ra giống với màu tôi đã nhận được trên đầu ra ogre3d của tôi.

Dù sao di chuyển trên ..

Một khi tôi đã này đã tìm ra tôi đã có thể tạo ra các kết cấu trong Ogre và vượt qua nó trên như sau

//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(); 

Vì vậy, bây giờ tôi có một kết cấu tôi có thể sử dụng như một chỉ số với một số giá trị mà tôi đã thêm vào để thử nghiệm, các giá trị này cuối cùng sẽ được điền vào thời gian chạy bằng cách nhấp vào ô xếp.

Bây giờ để vượt qua kết cấu này qua tôi đã phải vượt qua nó để các kỹ thuật chính xác và vượt qua trong các tài liệu của tôi, điều này đã được thực hiện như sau:

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");  

này qua hai giá trị quá, mapSize là kích thước của bản đồ trong ô (giả sử một hình vuông) và tas là kích thước bản đồ kết cấu (số hình vuông kết cấu khác nhau trên toàn bộ chiều rộng của bản đồ).

Để cho phép các tài liệu của tôi để hiểu những gì tôi vừa được thông qua tại tôi cần phải sửa đổi tập tin tài liệu của tôi một chút như sau:

// 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 
}    
} 

Và vượt qua tôi được xác định lại hơi quá

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 
} 
} 

Sau đó tôi viết lại chương trình phân đoạn kết cấu cg để xem xét các thay đổi mà tôi đã thực hiện.

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; 
} 
} 

Điều này tính toán đúng texel cần thiết từ bản đồ kết cấu, nó cũng phủ một lưới mờ trên đầu bằng cách kết hợp 80% màu texel và 20% trắng.

Nếu bản đồ kết cấu không có chỉ số màu sắc theo quy định của kết cấu chỉ số sau đó nó chỉ kết quả đầu ra màu đen (Đây là chủ yếu vì vậy nó rất dễ dàng để phát hiện.

Dưới đây là một ví dụ về đầu ra bằng cách sử dụng . 2 x 2 texture atlas

enter image description here

+0

@TheSHEEEP Hy vọng điều này sẽ giúp/bạn quan tâm. –

+0

Chắc chắn hữu ích, cảm ơn :) – TheSHEEEP

+0

@ TheSHEEEP Không có vấn đề, cũng trong trường hợp bạn đang tự hỏi, tôi quên đề cập đến hình ảnh kết xuất ở phía dưới là không thực sự khá những gì bạn nhận được với mã ở trên. Đoạn mã trên đặt một lưới bán trong suốt màu trắng ở trên, hình ảnh không tính đến kết cấu bên dưới lưới và chỉ vẽ màu đen. –

Các vấn đề liên quan