It is currently Tue May 26, 2020 2:04 pm

 All times are UTC

 Page 1 of 1 [ 6 posts ]
 Print view Previous topic | Next topic
Author Message
 Post subject: Question about material ids and marching cubesPosted: Mon Apr 21, 2014 2:57 pm

Joined: Tue Apr 08, 2014 5:10 pm
Posts: 124
I am experimenting with the material ids now.

with cubic extractor I don't have problems, but with the MArching Cubes I get somehow non-perfectly-smooth result. How can I fix that?

Attachment:

mids.jpg [ 53.19 KiB | Viewed 9371 times ]

Attachment:

mids2.jpg [ 57.12 KiB | Viewed 9371 times ]

Useful snippets:
Code:
SVT& SVT::operator +(const SVT &other)
{
if(this->material==0) this->material = other.material;
this->density += other.density;
return *this;
}

SVT& SVT::operator -(const SVT &other)
{
if(this->material==0) this->material = other.material;
this->density -= other.density;
return *this;
}

SVT& SVT::operator /(const int &other)
{
this->density /= other;
return *this;
}
/**/

SVT& SVT::operator +=(const SVT &other)
{
if(this->material==0) this->material = other.material;
this->density += other.density;
return *this;
}

SVT& SVT::operator -=(const SVT &other)
{
if(this->material==0) this->material = other.material;
this->density -= other.density;
return *this;
}

SVT& SVT::operator /=(const int &other)
{
this->density /= other;
return *this;
}
...
//Smooth chunk

RawVolume<SVT> tempVolume(Region(-1,-1,-1,c->sx+1,c->sy+1,c->sz+1));
LowPassFilter< RawVolume<SVT>, RawVolume<SVT>, SVT >
lpf(c->voxdata,     Region(-1,-1,-1,c->sx+1,c->sy+1,c->sz+1),
&tempVolume,    Region(-1,-1,-1,c->sx+1,c->sy+1,c->sz+1),
3);
lpf.execute();

MarchingCubesSurfaceExtractor< RawVolume<SVT>, PGFMarchingCubesController >
ext2(&tempVolume, Region(0,0,0,c->sx,c->sy,c->sz), c->newmesh);
ext2.execute();
...
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();
no->position(vertex_pos.getX(), vertex_pos.getY(), vertex_pos.getZ());
no->normal(vertex.getNormal().getX(), vertex.getNormal().getY(),  vertex.getNormal().getZ());
Ogre::Vector4 color;
int mid = vertex.getMaterial();
switch(mid)
{
case   0:   color =    Ogre::Vector4(   0   ,   0   ,   0   ,   0   );   break;
case   1:   color =    Ogre::Vector4(   0   ,   0   ,   0   ,   1   );   break;
case   2:   color =    Ogre::Vector4(   0   ,   0   ,   1   ,   0   );   break;
case   3:   color =    Ogre::Vector4(   0   ,   0   ,   1   ,   1   );   break;
case   4:   color =    Ogre::Vector4(   0   ,   1   ,   0   ,   0   );   break;
case   5:   color =    Ogre::Vector4(   0   ,   1   ,   0   ,   1   );   break;
case   6:   color =    Ogre::Vector4(   0   ,   1   ,   1   ,   0   );   break;
case   7:   color =    Ogre::Vector4(   0   ,   1   ,   1   ,   1   );   break;
case   8:   color =    Ogre::Vector4(   1   ,   0   ,   0   ,   0   );   break;
case   9:   color =    Ogre::Vector4(   1   ,   0   ,   0   ,   1   );   break;
case   10:   color =    Ogre::Vector4(   1   ,   0   ,   1   ,   0   );   break;
case   11:   color =    Ogre::Vector4(   1   ,   0   ,   1   ,   1   );   break;
case   12:   color =    Ogre::Vector4(   1   ,   1   ,   0   ,   0   );   break;
case   13:   color =    Ogre::Vector4(   1   ,   1   ,   0   ,   1   );   break;
case   14:   color =    Ogre::Vector4(   1   ,   1   ,   1   ,   0   );   break;
case   15:   color =    Ogre::Vector4(   1   ,   1   ,   1   ,   1   );   break;
}
no->colour(color.x,color.y,color.z,color.w);
...

struct vsout
{
float4 op: POSITION;    // Transformed vertex position
float3 uv: TEXCOORD0;    // UV0
float3 nm: TEXCOORD1;
float4 cl: COLOR;
};

vsout vert(
// Vertex Inputs
float4 position     : POSITION,    // Vertex position in model space
float3 texCoord0    : TEXCOORD0,   // Texture UV set 0
float3 normal       : NORMAL,
float4 color      : COLOR,
// Model Level Inputs
uniform float4x4 WVPMAT
)
{
vsout o;
float4 p = mul(WVPMAT, position);
o.op = p;
o.nm = normal;
o.uv = position.xyz /1 * float3(-1,1,1) + 0.5;
o.cl = color;
return o;
}

void frag(
// Pixel Inputs
float3 pos        : TEXCOORD0,   // UV interpolated for current pixel
float3 vnormal    : TEXCOORD1,
float4 col        : COLOR,      // the encoded material id

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

// Model Level Inputs
uniform sampler2D texture)        // Texture we're going to use
{
color = col - (1-pos.z/70)+0.4;
}

Top

 Post subject: Re: Question about material ids and marching cubesPosted: Tue Apr 22, 2014 6:37 pm
 Developer

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
I think that multiple materials with Marching Cubes does not have a simple solution. The problem here is that each voxel has a single material, but vertices are placed between voxels. How should the material of the vertex be decided? Taking the average doesn't make sense, but taking the maximum is one option (though it's not clear that it's correct).

I think you need to consider which values you assign to voxels, what threshold you use, how you compute a vertices' material from the materials of the surrounding voxels, and how you use these material ID's in the shader. Actually I don't have an exact answer here, but look at the MarhcingCubesController and the comments in it.

You might also find this interesting, though it's old and I'm not sure I still agree with the solution I proposed. It explains the problem though: http://books.google.com/books?id=WNfD2u8nIlIC&lpg=PR1&dq=game%20engine%20gems&pg=PA39#v=onepage&q&f=false

In Cubiquity we have a more complex and powerful approach, where we store several material ID's with each voxel and also with each vertex. This gives more flexibility with controlling the blending, but at the moment the code is on a seperate branch of PolyVox. We'll try to merge it across once Cubiquity is released.

You might also find it looks better when you are blending textures rather than solid colors.

Top

 Post subject: Re: Question about material ids and marching cubesPosted: Wed Apr 23, 2014 2:53 pm

Joined: Tue Apr 08, 2014 5:10 pm
Posts: 124
I think that I will try with 3D texture containing color-encoded material IDs and sampling it in the Pixel shader, then based on color differences between passed tex coords and snapped tex coords the blending factor will be applied. This will be limited to 16 materials, but will not be so perfect.
We don't need material IDs in the vertex declarations AT ALL in this case

I already tried with similar solution, encoding blend factors in 3D Texture's RGBA, but this had limit of 4 materials, which is not a solution (I need at least 15 materials to be happy), So I will now play with encoding at least 16 materials this way. Hope I won't hit the Shader Model Limitations with this approach - and conditional branching is huge bottleneck to be work-arounded.

About the textures, they looked so terrible and "teethy" like these control colors. Going with 3D Textures now. One chunk is 16x16x128 so I feel like 100 3D Textures won't be so big bottleneck. Or they will? I have to test.

Top

 Post subject: Re: Question about material ids and marching cubesPosted: Thu Apr 24, 2014 3:10 pm

Joined: Tue Apr 08, 2014 5:10 pm
Posts: 124
The implementation with 16 materials is impossible and VERY slow. So I ended up with my 4-materials approach and multi-passing.

This is the result after applying 3D texture lookup - definitely smooth

Now I will make multi-pass implementation, a pass can only render 4 materials.

Attachment:

multicolor.jpg [ 213.73 KiB | Viewed 9348 times ]

This is the CG Fragment shader I use:

Code:
void frag(
// Pixel Inputs
float3 Position        : TEXCOORD0,   // UV interpolated for current pixel
float4 VertexNormal      : TEXCOORD1,
float4 col            : COLOR,
float4 ps,

// Outputs
out float4 color    : COLOR
)
{
//two samplers
float4 mids = tex3D(tx3d, Position);

float scale = 8;
float4 m0 = tex2D(tex1, Position*scale);
float4 m1 = tex2D(tex2, Position*scale);
float4 m2 = tex2D(tex3, Position*scale);
float4 m3 = tex2D(tex4, Position*scale);

color = m0*mids.x + m1*mids.y + m2*mids.z + m3*mids.w;

return;
}

The algorithm is simple: you have N passes, a pass for 4 materials. If you have 6 materials, you need 2 passes.

For each pass you make a volume texture, RGBA, every channel is blend weight.

You must only use colors: (1,0,0,0), (0,1,0,0), (0,0,1,0), (0,0,0,1).
Materials that does not belong to this pass must be set to (0,0,0,0).

First pass fills everything, next passes must blend with previous pass's result.

The algorighm is memory-intensive as we have (passes/4) count of volume textures.
I am optimizing this per chunk - if a chunk have only 3 materials, I render them in one pass only - In Ogre 3D, I am generating material per chunk.

Vertex shader does nothing.
NO material IDs are needed in the resulting mesh, they are interpolated in the volume texture. Interpolation is not breaking anything as we have alpha-peer-channel.

Hope this technique helps anybody.

p.s. please add some plugin to not break layout on img

Top

 Post subject: Re: Question about material ids and marching cubesPosted: Fri Apr 25, 2014 8:19 am
 Developer

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
Very interesting! If I understand you correctly then you are using the RGBA channels of the 3D textures to encode the presence of up to four different materials? This means that each material is interpolated separately and so you get the smooth blending?

If the above is correct then this is conceptually similar to what we do in Cubiquity, except that we store all four material 'strengths' as RGBA components of a vertex color (rather than as a single maerial id). Again they are then interpolated separately. But this more flexible vertex format is what we added to the Cubiquity branch of PolyVox and which should be merged across to the main branch in the future.

Anyway, it's good to see that it is working well for you.

Top

 Post subject: Re: Question about material ids and marching cubesPosted: Fri Apr 25, 2014 10:08 am

Joined: Tue Apr 08, 2014 5:10 pm
Posts: 124
Exactly. Overusing the Hardware interpolation of 3D textures.

Code:
float4 mids = tex3D(tx3d, Position);

This line gets the interpolated color. Which means - interpolated material alphas
Because Source Colors are only 1000, 0100, 0010, 0001, and... 0000 for materials not intended to be drawn on current pass

Then I sample the 4 material textures:
Code:
float4 m0 = tex2D(tex1, Position*scale);
float4 m1 = tex2D(tex2, Position*scale);
float4 m2 = tex2D(tex3, Position*scale);
float4 m3 = tex2D(tex4, Position*scale);

... and multiply them by the interpolated alphas
Code:
color = m0*mids.x + m1*mids.y + m2*mids.z + m3*mids.w;

Well, however, this is NOT a triplanar texturing But once we have a way to seamlessly blend materials based on 3D Texture with material IDs, triplanar texturing is no longer a problem.

Quote:
should be merged across to the main branch in the future

I hope you merge back soon.

The only drawback of my approach is the memory usage - maintaining n 3D textures per chunk, where n = MaterialCount / 4. Plus, I will make additional one 3D texture that holds Light level and possibly other things.

Plus a 2D texture for biome / climate lookup.

Top

 Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending
 Page 1 of 1 [ 6 posts ]

 All times are UTC

#### Who is online

Users browsing this forum: Bing [Bot] and 17 guests

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

Search for:
 Jump to:  Select a forum ------------------ General Discussion Forums    General Discussion PolyVox Forums    PolyVox Discussion    PolyVox Bugs    Showcase Cubiquity Forums    Cubiquity Discussion Voxeliens Forums    Voxeliens Discussion    Voxeliens Support
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Theme created StylerBB.net