It is currently Sat Dec 14, 2019 9:05 am


All times are UTC




Post new topic Reply to topic  [ 52 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next
Author Message
 Post subject: Re: PolyVox and Ogre3D
PostPosted: Sun Oct 10, 2010 9:33 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
Yep, this is true, but as you say it's also the worst case scenario. I guess you are the only person who knows what the average case will be for your program.

Another option is to provide multiple textures to the shader in different texture units ('texture_unit' in Ogre). Again this is quite easy but only a limited number are supported depending on the GPU/DirectX. And it's probably slower than a texture atlas.

The 'perfect' solution is texture arrays, but these are only available from DirectX 10. But basically you have several options, it's just a case of seeing what is fastest/easiest/best for your scenario.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: PolyVox and Ogre3D
PostPosted: Sun Oct 10, 2010 12:34 pm 

Joined: Sun Oct 03, 2010 10:13 pm
Posts: 73
I will think over this a bit more before deciding. For now there is one error left which I was trying to find for the last few days.
I've got two directional lights in my scene. Here's what I think it is supposed to look like:
Image

And here how it looks if I just move the mouse for one pixel:
Image

I don't know why this happens, as you can see sometimes it's right, sometimes wrong. This was present even before the shader was used. I already tried changing some shadow parameters for my Camera and the SceneManager but to no avail. I think the black stuff are the shadows, interestingly I can't see them until I'm very close to the voxels. This doesn't apply to any other Entities/Meshes in the scene. You saw the code for the ManualObject generation, did I do something else wrong? This time I even set the normals. The new code is here just to make sure it's right:
Code:
    PolyVox::CubicSurfaceExtractor<PolyVox::MaterialDensityPair44> surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh);
    surfaceExtractor.execute();

    if ( PVWorld != NULL ) {
        PVWorldNode->detachObject(PVWorld);
        scenemgr->destroyManualObject(PVWorld);
    }
    PVWorld = scenemgr->createManualObject("PVWorld");

    uint32_t noVertices = mesh.getNoOfVertices();
    uint32_t noIndices = mesh.getNoOfIndices();

    PVWorld->estimateVertexCount(noVertices);
    PVWorld->estimateIndexCount(noIndices);

    PVWorld->begin("ColouredCubicVoxel", Ogre::RenderOperation::OT_TRIANGLE_LIST);

    // vertices
    const std::vector<PolyVox::SurfaceVertex>& vVertices = mesh.getVertices();
    for (unsigned int i=0; i<noVertices; i++) {
        const PolyVox::Vector3DFloat& pos = vVertices[i].getPosition();
        PVWorld->position(pos.getX(), pos.getY(), pos.getZ());
        const PolyVox::Vector3DFloat& normal = vVertices[i].getNormal();
        PVWorld->normal(normal.getX(), normal.getY(), normal.getZ());
    }

    // indices
    const std::vector<uint32_t>& vIndices = mesh.getIndices();
    for (unsigned int i=0; i<noIndices; i++) {
        PVWorld->index( vIndices[i] );
    }

    PVWorld->end();

    if ( PVWorldNode == NULL ) {
        PVWorldNode = scenemgr->getRootSceneNode()->createChildSceneNode();
    }
    PVWorldNode->attachObject(PVWorld);
    PVWorldNode->setScale(100.0, 100.0, 100.0);
    PVWorldNode->setPosition(0.0, 0.0, 0.0);


Another thing I wonder about, if the createSphereInVolume function creates a sphere in the center and I position the resulting ManualObject at 0,0,0, why is the sphere still so far away from the house which is at position 0,0,0, too?
Image
One thing I just remembered: I'm using SHADOWTYPE_TEXTURE_MODULATIVE because Stencil shadows didn't work because the index count of the resulting mesh was too high. Could this have to do with this?

I hope I'm not asking too many questions, maybe I should ask this at the Ogre forums instead...


Top
Offline Profile  
Reply with quote  
 Post subject: Re: PolyVox and Ogre3D
PostPosted: Sun Oct 10, 2010 4:48 pm 

Joined: Sun Oct 03, 2010 10:13 pm
Posts: 73
Ok, probably answering myself: With texture shadows an Entity/MovableObject can only either be a shadow caster OR shadow receiver. I had activated both which obviously doesn't work. However I need self-shadowing on the voxel world (maybe I'll come up with another solution).
For now I made the volume smaller (only 32^3 voxels) and switched back to stencil shadows. However the result was not as expected:
Image
Any ideas on that?


Top
Offline Profile  
Reply with quote  
 Post subject: Re: PolyVox and Ogre3D
PostPosted: Sun Oct 10, 2010 4:50 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
The shadow prroblems look like 'shadow acne', which is a fairly common problem when working with shadow maps. Google for this term and you'll probably find more information. Typically one option is to render the back faces of objects into the shadow maps rather than the front faces. But shadowing a a suprisingly complex area and it rarely 'just works'. And yes, you might find more help on the Ogre forums for this one.

Ok, I've just seen your update. I think you should ask on the Ogre forums, but generally you need to define extra information for shadow volumes. Some kind of 'edge lists' I think.

AndiNo wrote:
Another thing I wonder about, if the createSphereInVolume function creates a sphere in the center and I position the resulting ManualObject at 0,0,0, why is the sphere still so far away from the house which is at position 0,0,0, too?


The volume is not centered at (0,0,0). The position (0,0,0) is instead the lower corner. PolyVox never generates negative values for the vertex positions


Top
Offline Profile  
Reply with quote  
 Post subject: Re: PolyVox and Ogre3D
PostPosted: Sun Oct 10, 2010 10:04 pm 

Joined: Sun Oct 03, 2010 10:13 pm
Posts: 73
From reading on the forums and Google about "shadow acne" and other shadow problems I think I might try converting the ManualObject into a Mesh and then recalculate its edgelist. It's worth a try.

I observed that this Z-fighting only happens when using the shader. If I use a standard material like Ogre/Skin then the shadows get projected onto the sphere as expected - nearly. :) But I will post that in the Ogre forums. Might be the same problem after all...
To be honest I didn't expect shadows to be so much work ;) Anyway thanks for the help!


Top
Offline Profile  
Reply with quote  
 Post subject: Re: PolyVox and Ogre3D
PostPosted: Thu Oct 14, 2010 9:46 pm 

Joined: Sun Oct 03, 2010 10:13 pm
Posts: 73
Hi again! I've put shadows to the back of my todo list for a while to do some more coding on gameplay logic.
One thing I noticed is when you put a block at the outmost coordinate of a volume no mesh data will be generated for it:
Image
I don't know if that is intended, however I think it will give me difficulties in the future when trying to use many volumes to make up the world. Is that an error or is there any way I can change this?


Top
Offline Profile  
Reply with quote  
 Post subject: Re: PolyVox and Ogre3D
PostPosted: Thu Oct 14, 2010 9:50 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
It's something I'm aware of... but I'm not sure what will be done about it yet. In Thermite I don't use more than one volume at a time and simply make sure the outer voxels layer of are set to zero. But I'm doing some work on the surface extractor at the moment so we'll see what come of it.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: PolyVox and Ogre3D
PostPosted: Fri Oct 15, 2010 8:06 am 

Joined: Sun Oct 03, 2010 10:13 pm
Posts: 73
Hey, nearly all the compile warnings are gone! :) Nice!
A single one remains that is in PolyVox\library\PolyVoxCore\include\CubicSurfaceExtractor.inl at line 34. It's about initialization order of member variables. You have to change the constructor from
Code:
        :m_volData(volData)
        ,m_sampVolume(volData)
        ,m_regSizeInVoxels(region)
        ,m_meshCurrent(result)

to
Code:
        :m_volData(volData)
        ,m_sampVolume(volData)
        ,m_meshCurrent(result)
        ,m_regSizeInVoxels(region)


One question I've come up with is what PolyVox regions actually do. My idea is that in Thermite you have one big volume and when you need to change it you don't regenerate the whole mesh, you just take a smaller region out of the volume and update it to reduce processing time. Is that right? The problem is the Doxygen generated help page of the region class has absolutely no description in it so I can only assume what it does... But if I want to create a "streaming" world I would be better off using multiple volumes I think as it would be easier to manage.


edit:
I'm currently trying to get the texture atlas shader to work. I've already accomplished a few things but now I'm stuck. I want to store the voxel material in the vertex colour and use this in the shader to calculate the pixels. However it seems whatever value I store in the vertex colour will be changed although my code doesn't do it. Here's part of my C++ code:
Code:
    const std::vector<PolyVox::SurfaceVertex>& vVertices = mesh.getVertices();
    for (unsigned int i=0; i<noVertices; i++) {
        // position
        const PolyVox::Vector3DFloat& pos = vVertices[i].getPosition();
        PVWorld->position(pos.getX(), pos.getY(), pos.getZ());
        // normal
        const PolyVox::Vector3DFloat& normal = vVertices[i].getNormal();
        PVWorld->normal(normal.getX(), normal.getY(), normal.getZ());
        // colour/material
        Ogre::ColourValue val;
        uint8_t material = vVertices[i].getMaterial() + 0.5;
        val.r = 0.453f;
        val.g = 0.0f;
        val.b = 0.0f;
        val.a = 1.0f;
        PVWorld->colour(val);
    }

My shader code:
Code:
#define VOXELSCALE 100.0
#define VOXELCENTEROFFSET 0.5
// pixel size of tex atlas
#define TEXATLASSIZE 256
// pixel per single texture
#define TEXATLAS_TEXSIZE 16
// number of textures per row
#define TEXATLAS_NUMTEX (TEXATLASSIZE / TEXATLAS_TEXSIZE)
// size of a single texture in 0.0 - 1.0 values
#define TEXATLAS_TEXSIZE_NORMALIZED ((float)TEXATLAS_TEXSIZE / (float)TEXATLASSIZE)

void ColouredCubicVoxelVP(
    float4 inPosition    : POSITION,
    float4 inNormal        : NORMAL,
    float4 inColor        : COLOR,

    out float4 outClipPosition    : POSITION,
    out float4 outWorldPosition    : TEXCOORD0,
    out float4 outWorldNormal    : TEXCOORD1,
    out float4 outColor            : TEXCOORD2,

    uniform float4x4 world,
    uniform float4x4 viewProj
    )
{
    //Compute the world space position
    outWorldPosition = mul(world, inPosition);

    //Just pass though the normals without transforming them in any way. No rotation occurs.
    outWorldNormal = inNormal;

    //Compute the clip space position
    outClipPosition = mul(viewProj, outWorldPosition);

    outColor = inColor;
}

void ColouredCubicVoxelFP(
    float4 inPosition        : POSITION,
    float4 inWorldPosition    : TEXCOORD0,
    float4 inWorldNormal    : TEXCOORD1,
    float4 inColor            : TEXCOORD2,

    uniform sampler2D texAtlas    : TEXUNIT0,

    out float4 result        : COLOR)
{
    inWorldNormal = normalize(inWorldNormal);

    float3 col;

    //World position is used as texture coordinates. Choose which
    //two components of world position to use based on normal. Could
    //optionally use a different texture for each face here as well.
    float2 pos;
    if(inWorldNormal. x > 0.5)
    {
        col = tex2D(texAtlas, (inWorldPosition.yz / VOXELSCALE) + VOXELCENTEROFFSET);
    }

    if(inWorldNormal. x < -0.5)
    {
        col = tex2D(texAtlas, (inWorldPosition.yz / VOXELSCALE) + VOXELCENTEROFFSET);
    }

    // top
    if(inWorldNormal. y > 0.5)
    {
        pos = ((inWorldPosition.xz / VOXELSCALE) + VOXELCENTEROFFSET) / TEXATLAS_NUMTEX;
        if ( inColor[0] == 0.453 ) {
            col=0;
        }
        else {
            col = tex2D(texAtlas, pos);
        }
    }

    // bottom
    if(inWorldNormal. y < -0.5)
    {
        col = tex2D(texAtlas, (inWorldPosition.xz / VOXELSCALE) + VOXELCENTEROFFSET);
    }

    if(inWorldNormal. z > 0.5)
    {
        col = tex2D(texAtlas, (inWorldPosition.xy / VOXELSCALE) + VOXELCENTEROFFSET);
    }

    if(inWorldNormal. z < -0.5)
    {
        col = tex2D(texAtlas, (inWorldPosition.xy / VOXELSCALE) + VOXELCENTEROFFSET);
    }

    result = float4(col, 1.0);
}

I only changed the code for the top voxel face. It checks if the incoming colour value is the same as the one I stored in the vertex. However the faces are NOT black, so the values differ...
BTW, is there a program to debug shaders? Maybe I should start looking for one :)


Top
Offline Profile  
Reply with quote  
 Post subject: Re: PolyVox and Ogre3D
PostPosted: Sat Oct 16, 2010 3:16 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
Hi, I can't write much now, but you should start by seeing if vertex colours are getting through. For example, what if you replace the fragment program with just 'result = inColor'? And yes, both NVIDIA and ATI have shaded debuggers available. The NVIDIA one is PerfHUD.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: PolyVox and Ogre3D
PostPosted: Sun Oct 17, 2010 8:14 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
Right, I have time again now :-)

Regarding the Region class, your understanding is basically corect. It doesn't really 'do ' anything - it's just a convienient way to represent a particular region of the volume.

PolyVox has no support for streaming volumes and I have no plans to add it myself as it's not something I need. But if I were to implement such support I would probably do it by modifying the Volume class. The Volume class already stores data as a set of 'blocks', and probably I would unload these blocks from memory (storing them back to disk) if they hadn't been used for a while. So only the few hundred most recently used blocks would be in memory at any given time.

But if you want to implement streaming with what is available at the moment the probably you should store the world accross many volumes. This is what our other user 'beyzend' is doing, so maybe you can ask him for more info.

How big do you actually want your volumes to be?

Oh, and the AMD/ATI shader debugger is called PerfStudio.


Top
Offline Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 52 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 5 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