Jump to content
  • Advertisement
Sign in to follow this  
SlimTimmy

holes in terrain mesh

This topic is 4820 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

My terrain, which is rendered based on a heightmap, sometimes contains little holes (these are just one pixel big). Changing the behaviour flag from D3DCREATE_HARDWARE_VERTEXPROCESSING to D3DCREATE_SOFTWARE_VERTEXPROCESSING (or running with the debug runtime of DirectX), solves this problem: the artifacts do not occur anymore. Is this just a hardware issue (I have a 6600GT)? Or may a different driver help? Another strange thing: The holes appear after some seconds (around 5) and are not visible at the start of the program. What could that mean?

Share this post


Link to post
Share on other sites
Advertisement
Does it occur using the reference rasteriser? It may be a bug in your code that is hidden by a more forgiving software processor and the reference raterizer is normally the final word.

Share this post


Link to post
Share on other sites
You might be overwriting a vertex or index buffer. I had a problem like this with an ATI 9800 Pro. The program would cause the machine to bluescreen on an ATI X800, but get bizarre artifacts with the 9800.

Share this post


Link to post
Share on other sites
My first and only guess would be T-Junction problems. Everytime I've seen little "empty" pixels in the past it was because of a T-Junction problem! HW vs SW vertex processing probably generates screen space vertex coordinates with tiny differences and that's why you probably don't see the problem with SW processing even though it's there.

Share this post


Link to post
Share on other sites
I did some additional tests and i'll present you the results. Maybe you know how I could fix this problem.
I'm currently using a very simple vertex shader (a position gets transformed). After switching to the fixed function pipeline the pixel errors do not occur anymore. (btw: Does the graphics card emulate the ffp using shaders?)
Another strange result:
I made use of an indexed triangle list to improve the performance. I then switched to an unindexed list and the holes disappeared.
What can you gather from that?
And why do those holes appear after a certain time?

Share this post


Link to post
Share on other sites
Quote:

Does it occur using the reference rasteriser? It may be a bug in your code that is hidden by a more forgiving software processor and the reference raterizer is normally the final word.


I rendered the scene with the reference rasterizer, too. But the holes are not visible. Does this imply that the graphics card isn't working correctly?
Could the driver cause such a bizarre behaviour?

Quote:

My first and only guess would be T-Junction problems. Everytime I've seen little "empty" pixels in the past it was because of a T-Junction problem! HW vs SW vertex processing probably generates screen space vertex coordinates with tiny differences and that's why you probably don't see the problem with SW processing even though it's there.


T-cracks are often the reason for such pixel errors, but not in this case: I do not use any type of LOD, there are no vertices which lie at the edge of another triangle.

Here are the most important code snippets:

Initialization:

typedef D3DXVECTOR3 TerrainVertex;

const size_t HeightmapSize = 129;
const size_t NumTriangles = (HeightmapSize-1) * (HeightmapSize-1) * 2;
const size_t NumIndices = NumTriangles * 3;
const size_t NumVertices = HeightmapSize * HeightmapSize;


const D3DVERTEXELEMENT9 DeclArray[] =
{
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
D3DDECL_END()
};

Device->CreateVertexDeclaration(DeclArray, &TerrainDecl);

TerrainVertex Vertices[NumVertices];
WORD Indices[NumIndices];

TerrainVertex *v = Vertices;

for(size_t z = 0; z < HeightmapSize; ++z)
{
for(size_t x = 0; x < HeightmapSize; ++x)
{
v->x = static_cast<float>(x) * 10.0f;
v->y = 0.0f;
v->z = static_cast<float>(z) * 10.0f;

++v;
}
}

WORD *i = Indices;

for(size_t z = 0; z < HeightmapSize - 1; ++z)
{
for(size_t x = 0; x < HeightmapSize - 1; ++x)
{
*i = z * HeightmapSize + x; ++i;
*i = (z+1) * HeightmapSize + x; ++i;
*i = z * HeightmapSize + x + 1; ++i;

*i = (z+1) * HeightmapSize + x; ++i;
*i = (z+1) * HeightmapSize + x + 1; ++i;
*i = z * HeightmapSize + x + 1; ++i;
}
}


Device->CreateVertexBuffer( NumVertices * sizeof(TerrainVertex),
D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &TerrainVB, 0 );
void* Dest;
TerrainVB->Lock( 0, 0, &Dest, 0 );
memcpy( Dest, Vertices, sizeof(Vertices) );
TerrainVB->Unlock();

Device->CreateIndexBuffer( NumIndices * sizeof(WORD),
D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &TerrainIB, 0 );
TerrainIB->Lock( 0, 0, &Dest, 0 );
memcpy( Dest, Indices, sizeof(Indices) );
TerrainIB->Unlock();

LPD3DXBUFFER Shader;
D3DXAssembleShaderFromFile("shader.txt", 0, 0, 0, &Shader, 0);
Device->CreateVertexShader(reinterpret_cast<DWORD *>(Shader->GetBufferPointer()), &VertexShader);
Shader->Release();



Rendering code:

Device->Clear( 0, 0, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255,255,255), 1.0f, 0 );
Device->BeginScene();

D3DXMATRIX World, View, Proj, WorldViewProj;

float width = 1024.0f, height = 768.0f;
D3DXMatrixPerspectiveFovLH(&Proj, D3DXToRadian(45.0f), width / height, 1.0f, 2560.0f);
D3DXVECTOR3 At(177.57913f, 3.6251740f, 599.95532f),
Up(0.21075355, 0.97133797, 0.10993398f);
D3DXMatrixLookAtLH(&View, &Pos, &At, &Up);
D3DXMatrixIdentity(&World);

WorldViewProj = World * View * Proj;
D3DXMatrixTranspose(&WorldViewProj, &WorldViewProj);

Device->SetStreamSource(0, TerrainVB, 0, sizeof(TerrainVertex));
Device->SetIndices(TerrainIB);
Device->SetVertexDeclaration(TerrainDecl);

if( KEY_DOWN('T') )
{
Device->SetVertexShader(0);
Device->SetTransform(D3DTS_WORLD, &World);
Device->SetTransform(D3DTS_VIEW, &View);
Device->SetTransform(D3DTS_PROJECTION, &Proj);
}
else
{
Device->SetVertexDeclaration(TerrainDecl);
Device->SetVertexShaderConstantF(0, WorldViewProj, 4);
Device->SetVertexShader(VertexShader);
}

Device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, NumVertices, 0, NumIndices/3);

Device->EndScene();
Device->Present( 0, 0, 0, 0 );



And the vertex shader:

vs_1_1
def c4, 0.0f, 0.0f, 0.0f, 0.0f
dcl_position v0
dp4 oPos.x, v0, c0
dp4 oPos.y, v0, c1
dp4 oPos.z, v0, c2
dp4 oPos.w, v0, c3
mov oD0, c4


Share this post


Link to post
Share on other sites
I created a zip archive which contains the source code of the project, the compiled executable and the two images displayed below.
It would be nice if you could run the application and tell me whether you experienced the same problems as I did.


Please download the zip file

That's how it should look like:

And that's how the scene gets rendered after a couple of seconds:


You are able to switch between the ffp and vertex shaders by holding down the T key. (then the fixed function pipeline is used)

[Edited by - SlimTimmy on October 3, 2005 3:31:34 AM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!