It is currently Sat Aug 22, 2020 1:44 pm


All times are UTC




Post new topic Reply to topic  [ 13 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Issues with multiple materials and Ogre
PostPosted: Sun May 20, 2012 11:30 pm 

Joined: Sun May 20, 2012 12:50 am
Posts: 13
Hello.
I started out with an pretty simple brute force voxel engine myself using Ogre's manual objects and texture atlas, however I encountered some problems and instead of refactoring, I found PolyVox and I am very happy so far, it it such an awesome library!

Before I start I just want to say that I read pretty much most relevant forum topics about material issues and checked the documentation but can not get this to work.

However, I encountered an issue when trying to use different material that what is bound to the material id 0.
I am following the tutorial on "GLSL + Ogre for triplanar texturing and multiple textures" in the wiki.

When my material is 0, everything looks OK (the dark grey sphere).

However, when I try to change my material in all voxels from 0 to 1 I a white/black blur (like static junk on the TV).

I read all the topics on the forum and as suggest in here (Trouble with Triplanar Texturing of Multiple Materials) http://www.volumesoffun.com/phpBB3/viewtopic.php?f=14&t=375:
I have changed the vertices references, as suggested by that topic:
Code:
const PolyVox::PositionMaterialNormal& vertex0 = vertices.at(i0);
const PolyVox::PositionMaterialNormal& vertex1 = vertices.at(i1);
const PolyVox::PositionMaterialNormal& vertex2 = vertices.at(i2);


to:
Code:
const PolyVox::PositionMaterialNormal vertex0 = vertices.at(i0);
const PolyVox::PositionMaterialNormal vertex1 = vertices.at(i1);
const PolyVox::PositionMaterialNormal vertex2 = vertices.at(i2);


My material file looks like this, I am assuming by changing material id to 1 would render the MATERIAL_DIRT.png texture and so on, am I wrong about this?

terrain.material
Code:
vertex_program TriplanarVS glsl
{
   source triplanar_vertex_shader.txt
}
fragment_program TriplanarPS glsl
{
   source triplanar_pixel_shader.txt
}

material ApeTexture
{
   technique
   {
      pass
      {
         vertex_program_ref TriplanarVS
         {
         }

         fragment_program_ref TriplanarPS
         {
            param_named lightDirection float4 1 -0.7 1 0
            param_named tex0 int 0
            param_named tex1 int 1
            param_named tex2 int 2
            param_named tex3 int 3
            param_named tex4 int 4
         }
         texture_unit 0
         {
            texture MATERIAL_DEEPROCK.png 2d
         }
         texture_unit 1
         {
            texture MATERIAL_DIRT.png 2d
         }
         texture_unit 2
         {
            texture MATERIAL_GRASS.png 2d
         }
         texture_unit 3
         {
            texture MATERIAL_ROCK.png 2d
         }
         texture_unit 4
         {
            texture MATERIAL_WATER.png 2d
         }
      }
   }
}


Here is my source:
Code:
void OgreHardwareBufferObject::test2()
{
   SimpleVolume<MaterialDensityPair88> volData(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(31, 31, 31)));
   createSphereInVolume(volData, 5);

   SurfaceMesh<PositionMaterialNormal> mesh;
   SurfaceExtractor<SimpleVolume, MaterialDensityPair88>
      surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh);

   surfaceExtractor.execute();

   std::vector<PolyVox::PositionMaterialNormal>& vertices = mesh.m_vecVertices;
   std::vector<uint32_t>& indices = mesh.m_vecTriangleIndices;

   assert(indices.size() % 3 == 0);

   std::vector<MaterialAlpha> vertex_extra_data(vertices.size());
   for(uint32_t i = 0; i < indices.size(); i+=3) {
      uint32_t& i0 = indices.at(i);
      uint32_t& i1 = indices.at(i+1);
      uint32_t& i2 = indices.at(i+2);
      const PolyVox::PositionMaterialNormal vertex0 = vertices.at(i0);
      const PolyVox::PositionMaterialNormal vertex1 = vertices.at(i1);
      const PolyVox::PositionMaterialNormal vertex2 = vertices.at(i2);

      MaterialAlpha ma;
      ma.material[0] = vertex0.getMaterial();
      ma.material[1] = vertex1.getMaterial();
      ma.material[2] = vertex2.getMaterial();

      if(vertex0.getMaterial() != vertex1.getMaterial()) {
         if(vertex0.getMaterial() != vertex2.getMaterial()) {
            ma.alpha[0] = 1.0;
            ma.alpha[1] = 0.0;
            ma.alpha[2] = 0.0;
            vertex_extra_data.push_back(ma);
            i0 = vertices.size();
            vertices.push_back(vertex0);

            ma.alpha[0] = 0.0;
            ma.alpha[1] = 1.0;
            ma.alpha[2] = 0.0;
            vertex_extra_data.push_back(ma);
            i1 = vertices.size();
            vertices.push_back(vertex1);

            ma.alpha[0] = 0.0;
            ma.alpha[1] = 0.0;
            ma.alpha[2] = 1.0;
            vertex_extra_data.push_back(ma);
            i2 = vertices.size();
            vertices.push_back(vertex2);
         } else {
            // vertex 0 and 2 have the same material
            ma.alpha[0] = 0.5;
            ma.alpha[1] = 0.0;
            ma.alpha[2] = 0.5;
            vertex_extra_data.push_back(ma);
            i0 = vertices.size();
            vertices.push_back(vertex0);

            ma.alpha[0] = 0.0;
            ma.alpha[1] = 1.0;
            ma.alpha[2] = 0.0;
            vertex_extra_data.push_back(ma);
            i1 = vertices.size();
            vertices.push_back(vertex1);

            ma.alpha[0] = 0.5;
            ma.alpha[1] = 0.0;
            ma.alpha[2] = 0.5;
            vertex_extra_data.push_back(ma);
            i2 = vertices.size();
            vertices.push_back(vertex2);
         }
      } else {
         if(vertex0.getMaterial() != vertex2.getMaterial()) {
            // vertex 0 and 1 have same material
            ma.alpha[0] = 0.5;
            ma.alpha[1] = 0.5;
            ma.alpha[2] = 0.0;
            vertex_extra_data.push_back(ma);
            i0 = vertices.size();
            vertices.push_back(vertex0);

            ma.alpha[0] = 0.5;
            ma.alpha[1] = 0.5;
            ma.alpha[2] = 0.0;
            vertex_extra_data.push_back(ma);
            i1 = vertices.size();
            vertices.push_back(vertex1);

            ma.alpha[0] = 0.0;
            ma.alpha[1] = 0.0;
            ma.alpha[2] = 1.0;
            vertex_extra_data.push_back(ma);
            i2 = vertices.size();
            vertices.push_back(vertex2);
         } else {
            // all are equal
            ma.alpha[0] = 1.0/3.0;
            ma.alpha[1] = 1.0/3.0;
            ma.alpha[2] = 1.0/3.0;
            vertex_extra_data[i0] = ma;
            vertex_extra_data[i1] = ma;
            vertex_extra_data[i2] = ma;
         }
      }
   }

   Ogre::ManualObject* ogreMesh = mView->getSceneMgr()->createManualObject("PolyVox Mesh");
   ogreMesh->begin("ApeTexture", Ogre::RenderOperation::OT_TRIANGLE_LIST);
   ogreMesh->estimateVertexCount(vertices.size());
   ogreMesh->estimateIndexCount(indices.size());

   PolyVox::Vector3DFloat chunk_pos = PolyVox::Vector3DFloat(0, 0, 0);

   for(uint32_t i = 0; i < vertices.size(); i++) {
      const PolyVox::PositionMaterialNormal& vertex = vertices.at(i);
      const MaterialAlpha& ma = vertex_extra_data.at(i);
      PolyVox::Vector3DFloat vertex_pos = vertex.getPosition() + chunk_pos;
      ogreMesh->position(vertex_pos.getX(), vertex_pos.getY(), vertex_pos.getZ());
      ogreMesh->normal(vertex.getNormal().getX(), vertex.getNormal().getY(), vertex.getNormal().getZ());
      float x = vertex_pos.getX();
      float y = vertex_pos.getY();
      float z = vertex_pos.getZ();
      const float faktor = 50;
      for(int j = 0; j < 3; j++) {
         ogreMesh->textureCoord(x/faktor, y/faktor, z/faktor, ma.alpha[j]);
      }
      ogreMesh->textureCoord(ma.material[0], ma.material[1], ma.material[2]);
   }
   for(uint32_t i = 0; i < indices.size(); i++) {
      const uint32_t& index = indices.at(i);
      ogreMesh->index(index);
   }

   ogreMesh->end();

   Ogre::SceneNode* ogreNode = mView->getSceneMgr()->getRootSceneNode()->
      createChildSceneNode("Test", Ogre::Vector3(0, 0, 0));

   ogreNode->attachObject(ogreMesh);
}


Attachments:
VoxelsBroken.jpg
VoxelsBroken.jpg [ 65.24 KiB | Viewed 4803 times ]
VoxelsWorking.jpg
VoxelsWorking.jpg [ 8.82 KiB | Viewed 4803 times ]
Top
Offline Profile  
Reply with quote  
 Post subject: Re: Issues with multiple materials and Ogre
PostPosted: Mon May 21, 2012 8:13 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
I'm not overly familier with that tutorial but yes, I think it should probably behave as you suggest. To narrow down the issue I would suggest simplifying your shader code to return fixed colours for each material instead of sampling the textures. Perhaps modify the getColor() function something like this (untested):

Code:
if(texId == 0) {
      ret.col0 = float4(1.0, 0.0, 0.0, 1.0);
      ret.col1 = float4(1.0, 0.0, 0.0, 1.0);
      ret.col2 = float4(1.0, 0.0, 0.0, 1.0);
   } else if(texId == 1) {
      //Return blue
      ...
   } else if(texId == 2) {
      //Return green
      ...
   } else if(texId == 3) {
      //etc
   } else if(texId == 4) {
      //etc
   } else {
      //etc
   }


This will help determine whether the problem is with the material values coming from PolyVox or with the setup of your texture units in Ogre. If you can, make further simplifications to further narrow down the issue.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Issues with multiple materials and Ogre
PostPosted: Mon May 21, 2012 9:01 am 

Joined: Sun May 20, 2012 12:50 am
Posts: 13
Thank you for the quick response.

I updated the code as you requested:
Code:
threecolor getColor(vec4 texCoord, float texId)
{
   vec2 coord1 = texCoord.yz;
       vec2 coord2 = texCoord.zx;
      vec2 coord3 = texCoord.xy;
   threecolor ret;
   if(texId == 0) {
      ret.col0 = float4(0.0, 0.0, 0.0, 1.0);
            ret.col1 = float4(0.0, 0.0, 0.0, 1.0);
           ret.col2 = float4(0.0, 0.0, 0.0, 1.0);
   } else if(texId == 1) {
      ret.col0 = float4(1.0, 0.0, 0.0, 1.0);
            ret.col1 = float4(1.0, 0.0, 0.0, 1.0);
           ret.col2 = float4(1.0, 0.0, 0.0, 1.0);
   } else if(texId == 2) {
      ret.col0 = float4(0.0, 1.0, 0.0, 1.0);
            ret.col1 = float4(0.0, 1.0, 0.0, 1.0);
           ret.col2 = float4(0.0, 1.0, 0.0, 1.0);
   } else if(texId == 3) {
      ret.col0 = float4(0.0, 0.0, 1.0, 1.0);
            ret.col1 = float4(0.0, 0.0, 1.0, 1.0);
           ret.col2 = float4(0.0, 0.0, 1.0, 1.0);
   } else if(texId == 4) {
      ret.col0 = float4(1.0, 0.0, 1.0, 1.0);
            ret.col1 = float4(1.0, 0.0, 1.0, 1.0);
           ret.col2 = float4(1.0, 0.0, 1.0, 1.0);
   } else {
      // white
      ret.col0.x = 1.0;
      ret.col0.y = 1.0;
      ret.col0.z = 1.0;
      ret.col0.w = 1.0;
      ret.col1 = ret.col0;
      ret.col2 = ret.col0;
   }
   return ret;
}


I get the same distortion, but with colors of white and red instead of white and black.

My knowledge about shaders are regrettably close to zero.

Then, I did enable this little hack when generation the voxels, and ended up with a very distorted but colorful cube:
Code:
static uint8_t material = 0;
material++;
material = material % 4;
if(material == 0) material = 1;
MaterialDensityPair88 voxel = volData.getVoxelAt(x,y,z);
                                     
uint8_t uDensity = MaterialDensityPair88::getMaxDensity();
                              
voxel.setDensity(uDensity);
voxel.setMaterial(material);
volData.setVoxelAt(x, y, z, voxel);


Since the colors are returned properly, I guess the issue is in the main program. I will ask someone else to run the program, in case it has something to do with my hardware/drivers.


Attachments:
VoxelsBrokenColors.jpg
VoxelsBrokenColors.jpg [ 67.48 KiB | Viewed 4795 times ]
Top
Offline Profile  
Reply with quote  
 Post subject: Re: Issues with multiple materials and Ogre
PostPosted: Mon May 21, 2012 9:26 am 
User avatar

Joined: Wed Jan 26, 2011 3:20 pm
Posts: 203
Location: Germany
one thing... i know that "technically" this cannot happen, but since there is a lot of "white" which is only set when the else path is chosen in the shader (which is invalid), i am assuming that the texId is not truly 0, 1, 2, 3 or 4, but something close to that.
try changing the shader code to this:

Code:
if(texId < 0.5) {
      ret.col0 = float4(0.0, 0.0, 0.0, 1.0);
            ret.col1 = float4(0.0, 0.0, 0.0, 1.0);
           ret.col2 = float4(0.0, 0.0, 0.0, 1.0);
   } else if(texId < 1.5) {
      ret.col0 = float4(1.0, 0.0, 0.0, 1.0);
            ret.col1 = float4(1.0, 0.0, 0.0, 1.0);
           ret.col2 = float4(1.0, 0.0, 0.0, 1.0);
   } else if(texId < 2.5) {
      ret.col0 = float4(0.0, 1.0, 0.0, 1.0);
            ret.col1 = float4(0.0, 1.0, 0.0, 1.0);
           ret.col2 = float4(0.0, 1.0, 0.0, 1.0);
   } else if(texId < 3.5) {
      ret.col0 = float4(0.0, 0.0, 1.0, 1.0);
            ret.col1 = float4(0.0, 0.0, 1.0, 1.0);
           ret.col2 = float4(0.0, 0.0, 1.0, 1.0);
   } else if(texId < 4.5) {
      ret.col0 = float4(1.0, 0.0, 1.0, 1.0);
            ret.col1 = float4(1.0, 0.0, 1.0, 1.0);
           ret.col2 = float4(1.0, 0.0, 1.0, 1.0);
   } else {
      // white THIS IS AN ERROR, THIS SHOULD NEVER HAPPEN
      ret.col0.x = 1.0;
      ret.col0.y = 1.0;
      ret.col0.z = 1.0;
      ret.col0.w = 1.0;
      ret.col1 = ret.col0;
      ret.col2 = ret.col0;
   }


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Issues with multiple materials and Ogre
PostPosted: Mon May 21, 2012 9:32 am 

Joined: Sun May 20, 2012 12:50 am
Posts: 13
Yay, it worked :)

So much for technically impossible hehe :shock:

Do you have any pointers for me how to debug why these values are non integers?


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Issues with multiple materials and Ogre
PostPosted: Mon May 21, 2012 9:35 am 
User avatar

Joined: Wed Jan 26, 2011 3:20 pm
Posts: 203
Location: Germany
they are defined as float texID ;)
depending on your drivers and OS and cosmic rays (kidding) a value might be converted so many times between different floating point precisions and run through optimizers that you can never know of... it might just be off by one bit..
rule of thumb: "never use == on a float" (yes i am aware that this is my fuckup ;) )


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Issues with multiple materials and Ogre
PostPosted: Mon May 21, 2012 9:57 am 

Joined: Sun May 20, 2012 12:50 am
Posts: 13
It seems like the material ids are defined as int's in the ogre material:


Code:
material ApeTexture
{
   technique
   {
      pass
      {
         vertex_program_ref TriplanarVS
         {
         }

         fragment_program_ref TriplanarPS
         {
            param_named lightDirection float4 1 -0.7 1 0
            param_named tex0 int 0
            param_named tex1 int 1
            param_named tex2 int 2
            param_named tex3 int 3
            param_named tex4 int 4



OK, so you actually suggest to keep the shader program comparing with < and > instead of == ? It seems a bit volatile but I guess I have to live with that.

However, I seem to have another (probably related) issue.

It seems like the base color of my textures are used instead of the whole texture, please look at the screenshot.

I did update the shader program back to what the wiki specifies:

Code:
uniform vec4 lightDirection;
uniform sampler2D tex0;
uniform sampler2D tex1;
uniform sampler2D tex2;
uniform sampler2D tex3;
uniform sampler2D tex4;
uniform sampler2D tex5;
uniform sampler2D tex6;
uniform sampler2D tex7;
uniform sampler2D tex8;
uniform sampler2D tex9;
uniform sampler2D tex10;
uniform sampler2D tex11;
uniform sampler2D tex12;
uniform sampler2D tex13;
uniform sampler2D tex14;
uniform sampler2D tex15;

struct threecolor
{
   vec4 col0;
   vec4 col1;
   vec4 col2;
};

threecolor getColor(vec4 texCoord, float texId)
{
   vec2 coord1 = texCoord.yz;
       vec2 coord2 = texCoord.zx;
      vec2 coord3 = texCoord.xy;
   threecolor ret;
   if(texId < 0.5) {
      ret.col0 = texture2D( tex0, coord1) * texCoord.w;
      ret.col1 = texture2D( tex0, coord2) * texCoord.w;
      ret.col2 = texture2D( tex0, coord3) * texCoord.w;
   } else if(texId < 1.5) {
      ret.col0 = texture2D( tex1, coord1) * texCoord.w;
      ret.col1 = texture2D( tex1, coord2) * texCoord.w;
      ret.col2 = texture2D( tex1, coord3) * texCoord.w;
   } else if(texId < 2.5) {
      ret.col0 = texture2D( tex2, coord1) * texCoord.w;
      ret.col1 = texture2D( tex2, coord2) * texCoord.w;
      ret.col2 = texture2D( tex2, coord3) * texCoord.w;
   } else if(texId < 3.5) {
      ret.col0 = texture2D( tex3, coord1) * texCoord.w;
      ret.col1 = texture2D( tex3, coord2) * texCoord.w;
      ret.col2 = texture2D( tex3, coord3) * texCoord.w;
   } else if(texId < 4.5) {
      ret.col0 = texture2D( tex4, coord1) * texCoord.w;
      ret.col1 = texture2D( tex4, coord2) * texCoord.w;
      ret.col2 = texture2D( tex4, coord3) * texCoord.w;
   } else {
      // white
      ret.col0.x = 1.0;
      ret.col0.y = 1.0;
      ret.col0.z = 1.0;
      ret.col0.w = 1.0;
      ret.col1 = ret.col0;
      ret.col2 = ret.col0;
   }
   return ret;
}

void main() {
    vec3 absNormal;
    vec3 blend_weights;
    vec2 coord1;
    vec2 coord2;
    vec2 coord3;
   vec3 texIds = gl_TexCoord[4].xyz;
   vec4 blended_color;
    vec4 light;
    float ldn;
    float ambient = 0.200000;

   threecolor col0 = getColor( gl_TexCoord[1], texIds.x );
   threecolor col1 = getColor( gl_TexCoord[2], texIds.y );
   threecolor col2 = getColor( gl_TexCoord[3], texIds.z );
    threecolor col;

   col.col0 = col0.col0 + col1.col0 + col2.col0;
   col.col1 = col0.col1 + col1.col1 + col2.col1;
   col.col2 = col0.col2 + col1.col2 + col2.col2;

    absNormal = abs( gl_TexCoord[0].xyz );
    blend_weights = absNormal;
    blend_weights = (blend_weights - 0.267900);
    blend_weights = max( blend_weights, vec3( 0.000000));
    blend_weights /= vec3( ((blend_weights.x  + blend_weights.y ) + blend_weights.z ));
    blended_color = (col.col0  * blend_weights.x ) + (col.col1  * blend_weights.y ) + (col.col2  * blend_weights.z );
    light = ( -normalize( lightDirection ) );
    ldn = max( 0.000000, dot( light, gl_TexCoord[0]));
    gl_FragData[0] = vec4( blended_color * (ambient + ldn) );
}


Perhaps I done something wrong with the vertex shader?

Code:
void main() {
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    gl_TexCoord[0] = vec4(normalize( gl_Normal), 0.0);

    gl_TexCoord[1] = vec4(gl_MultiTexCoord0);
    gl_TexCoord[2] = vec4(gl_MultiTexCoord1);
    gl_TexCoord[3] = vec4(gl_MultiTexCoord2);

    gl_TexCoord[4] = vec4(gl_MultiTexCoord3);
}


Attachments:
VoxelsOnlyColors.jpg
VoxelsOnlyColors.jpg [ 17.04 KiB | Viewed 4788 times ]
Top
Offline Profile  
Reply with quote  
 Post subject: Re: Issues with multiple materials and Ogre
PostPosted: Mon May 21, 2012 10:36 am 
User avatar

Joined: Wed Jan 26, 2011 3:20 pm
Posts: 203
Location: Germany
while the texture numbers are set to integers, this is not relevant in our case.
the values passed from ogre are definitely floats. and we compare to those values.


try setting the "faktor=50" variable to 1 in the ogre c++ code, maybe it just looks odd due to the many colors and a bad texture scale


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Issues with multiple materials and Ogre
PostPosted: Mon May 21, 2012 10:51 am 

Joined: Sun May 20, 2012 12:50 am
Posts: 13
Just arrived at work, will try to increase the size of the sphere and turn up the textures, currently they are 256x256.

What I expected from is that each voxels wrap the texture (like what Minecraft does). I will try this later today when I get home.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Issues with multiple materials and Ogre
PostPosted: Mon May 21, 2012 12:36 pm 
User avatar

Joined: Wed Jan 26, 2011 3:20 pm
Posts: 203
Location: Germany
nope, the texture should wrap every 50 voxels ;) that's what the faktor is there for


Top
Offline Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Theme created StylerBB.net