Vertexshader - No z-test?

Started by
18 comments, last by Plerion 14 years, 3 months ago
Hello! Im not yet really friend with vertexshaders but i try to get :P. I managed pixelshaders pretty well but vertexshaders give me odd behaviour! I use the following shader:

float3 position;
float radius;
float4x4 viewProj;

struct VertexInput
{
  float4 pos : POSITION0;
};

struct PixelInput
{
  float4 pos : POSITION0;
  float2 data : TEXCOORD0;
};

PixelInput VShader(VertexInput input)
{
  float dX = input.pos.x - position.x;
  float dZ = input.pos.z - position.z;
  
  float tot = dX * dX + dZ * dZ;
  tot = sqrt(tot);
  
  PixelInput ret = (PixelInput)0;
  ret.pos = mul(input.pos, viewProj);
  if(tot <= radius)
    ret.data.r = 1;
  else
    ret.data.r = 0;
    
  return ret;
}

float4 MyShader(PixelInput pInput) : COLOR0
{
  float4 c1, c2;
  c1.r = c1.g = c1.b = c1.a = 1.0;
  c2.r = c2.g = c2.a = 1.0;
  c2.b = 0.0;

  if(pInput.data.r > 0)
    return c1;
  else
    return c2;
}

technique EntryPoint
{
    pass p1
    {
        VertexShader = compile vs_2_0 VShader();
        PixelShader = compile ps_2_0 MyShader();
    }
}
But when i use this shader to draw some triangles there is no more depthtest. It just displays whats rendered last on a pixel. Why is that effect occuring? A i doing something wrong (i guess)? Greetings Cromon
Advertisement
might sound stupid, but is the zbuffer enabled ?

d3ddevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE );

Hello!

Yes, its enabled:
void Render(){	g_Device->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);	g_Device->Clear(0, 0, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);	g_Device->BeginScene();		g_Device->SetTransform(D3DTS_PROJECTION, &matProj);		g_Device->SetTransform(D3DTS_VIEW, &matView);	g_Device->SetRenderState(D3DRS_LIGHTING, FALSE);	g_Device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);	g_Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);	UINT nPasses = 0;	g_Effect->Begin(&nPasses, 0);	for(UINT i = 0; i < nPasses; ++i)	{		g_Effect->BeginPass(i);		g_Device->SetFVF(Vertex::FVF);		g_Device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 3, vertices, Vertex::stride);		g_Effect->EndPass();	}	g_Effect->End();	g_Device->EndScene();	g_Device->Present(0, 0, 0, 0);}
What about turning on Z writing, so the depth buffer actually gets updated (D3DRS_ZWRITEENABLE) ? I don't know if it's on by default

Capturing this in a gpu debugger will show you exactly what render states are active and would be more useful to debug

The next question is going to be how are you sure that this is a depth test issue? Screenshots might help.

Also - is it guaranteed that the positions in your vertex stream are all 4 components and the W component of all of them is 1.0? Most people send a float3 position into the vert shader and create the float4 as float4( pos, 1.0f )
Yes, its turned on, but it has no effect. I depends on the order of my vertices what gets rendered! Thats how they look:
Vertex vertices[] ={	{ -5.0f, 0.0f, 0.0f, D3DCOLOR_XRGB(255, 0, 0) },	{ 5.0f, 0.0f, 0.0f, D3DCOLOR_XRGB(255, 0, 0) },	{ 0.0f, -3.0f, 0.0f, D3DCOLOR_XRGB(255, 0, 0) },	{ -5.0f, 0.0f, 0.0f, D3DCOLOR_XRGB(255, 255, 0) },	{ 5.0f, 0.0f, 0.0f, D3DCOLOR_XRGB(255, 255, 0) },	{ 0.0f, 3.0f, 0.0f, D3DCOLOR_XRGB(255, 255, 0) },	{ -5.0f, 0.0f, -2.0f, D3DCOLOR_XRGB(255, 255, 255) },	{ 5.0f, 0.0f, -2.0f, D3DCOLOR_XRGB(255, 255, 255) },	{ 0.0f, 3.0f, -2.0f, D3DCOLOR_XRGB(255, 255, 255) },};


So now the last triangle is on the top even if it has a z-value of -2. If i set the lower 3 vertices to the top its behind the other 2 as it should be.
Screenshots here:
With shader and triangle with -2.0f as the last:
http://www.imagr.eu/up/4b37d3499db0e_wsh.JPG

Without shader and the triangle with -2.0f (the white) as the last:
http://www.imagr.eu/up/4b37d36512a6a_osh1.JPG

Without shader and the triangle with -2.0f (the white) as the first:
http://www.imagr.eu/up/4b37d3a0815b2_osh2.JPG

With shader and the triangle with -2.0f as the first:
http://www.imagr.eu/up/4b37d3d1582dd_wsh2.JPG
As a sanity check, change this line in your shader to this:

ret.pos = mul(float4(input.pos.xyz,1.0f), viewProj);
Its still the same, always the last triangle rendered is the top. But i guess now that its not because of the shader because the image is also wrong whin i disable the shader!
Did you check the other stuff I suggested, like enabling D3DRS_ZWRITEENABLE ?

This topic is closed to new replies.

Advertisement