Skip to main content
GameDev.net gamedev.net
🔒 Locked

shadow volume problem

Started by jhq Jun 11, 2007 at 4:16 AM 1 replies 800+ views
Original Post
jhq
jhq
shadow volume demo with noise This is my shadow volume demo programmed by DX9. As you can see, it is not good, there is a lot of black noise on the occluder which really confuse me. Could anyone help me out? Below is my render() function(maybe it is a little long :) ):

void CShadowVolumeApplication::Render()
{
    //setup some variables
	D3DXVECTOR4 EyePos(0.0f, 60.0f, -60.0f, 0.0f);
	D3DXMatrixLookAtLH(&m_ViewMatrix, &(D3DXVECTOR3)EyePos,
		&D3DXVECTOR3(0.0f, 0.0f, 0.0f), &D3DXVECTOR3(0.0f, 1.0f, 0.0f));

	float Time = (float)GetTickCount() / 2000.0f;
	D3DXVECTOR4 LightPos(150.0f * sin(Time), 90.0f, 0.0f, 1.0f);

	D3DXVECTOR4 LightDir = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f) - LightPos;
	D3DXVec4Normalize(&LightDir, &LightDir);

	D3DXVECTOR4 Ambient(0.0f, 0.0f, 0.0f, 0.0f);
	m_pD3DDevice->SetVertexShaderConstantF(5, (float*)&Ambient, 1);

	D3DXVECTOR4 PushDistance(100.0f, 0.0f, 0.0f, 0.0f);
	m_pD3DDevice->SetVertexShaderConstantF(8, (float*)&PushDistance, 1);

	m_pD3DDevice->SetVertexDeclaration(m_pDeclaration);
	m_pD3DDevice->SetVertexShader(m_pBasicShader);

	//if I comment out this line, the noise will disappear,
    //but as you can expect, stippling effect will occur,
    //but I also think the noise also have something to do with this
	m_pD3DDevice->SetRenderState(D3DRS_DEPTHBIAS, 10);

    //draw the white plane
	RenderPlane();

	//draw the occluder
	D3DXMATRIX Rotation;
	D3DXMATRIX Translation;

	D3DXMatrixTranslation(&m_WorldMatrix, 20.0f, 10.0f, 0.0f);
	D3DXMATRIX ShaderMatrix = m_WorldMatrix * m_ViewMatrix * m_ProjectionMatrix;
	D3DXMatrixTranspose(&ShaderMatrix, &ShaderMatrix);
	m_pD3DDevice->SetVertexShaderConstantF(0, (float*)&ShaderMatrix, 4);

	D3DXMATRIX InverseWorld;
	float Det;
	D3DXMatrixInverse(&InverseWorld, &Det, &m_WorldMatrix);
	D3DXVec4Transform(&LightDir, &LightDir, &InverseWorld);
	D3DXVec4Normalize(&LightDir, &LightDir);
	m_pD3DDevice->SetVertexShaderConstantF(4, (float*)&LightDir, 1);

	D3DXVec4Transform(&LightPos, &LightPos, &InverseWorld);
	m_pD3DDevice->SetVertexShaderConstantF(7, (float*)&LightPos, 1);

	D3DXMatrixRotationY(&Rotation, (float)GetTickCount() / 1000.0f);
	D3DXMatrixTranslation(&Translation, 0.0f, 20.0f, 0.0f);
	m_WorldMatrix = Rotation * Translation;
	
	ShaderMatrix = m_WorldMatrix * m_ViewMatrix * m_ProjectionMatrix;
	D3DXMatrixTranspose(&ShaderMatrix, &ShaderMatrix);
	m_pD3DDevice->SetVertexShaderConstantF(0, (float*)&ShaderMatrix, 4);
	D3DXMatrixInverse(&InverseWorld, &Det, &m_WorldMatrix);
	D3DXVec4Transform(&LightDir, &LightDir, &InverseWorld);
	D3DXVec4Normalize(&LightDir, &LightDir);
	m_pD3DDevice->SetVertexShaderConstantF(4, (float*)&LightDir, 1);
	D3DXVec4Transform(&LightPos, &LightPos, &InverseWorld);
	m_pD3DDevice->SetVertexShaderConstantF(7, (float*)&LightPos, 1);

	m_pD3DDevice->SetStreamSource(0, m_pMeshVertexBuffer, 0, sizeof(MESH_VERTEX));
	m_pD3DDevice->SetIndices(m_pMeshIndexBuffer);
	m_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, m_pMesh->GetNumVertices(), 0,
		m_pMesh->GetNumFaces());//end draw of occluder

	//draw shadow volume in stencil buffer
	m_pD3DDevice->Clear(0, NULL, D3DCLEAR_STENCIL, 0, 1.0f, 0);
	m_pD3DDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
	m_pD3DDevice->SetRenderState(D3DRS_STENCILFUNC,   D3DCMP_ALWAYS);
	m_pD3DDevice->SetRenderState(D3DRS_STENCILPASS,   D3DSTENCILOP_INCR);
	m_pD3DDevice->SetRenderState(D3DRS_STENCILREF,    1);

	m_pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);

	m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
	m_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
	m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);

	m_pD3DDevice->SetVertexShader(m_pVolumeShader);

	m_pD3DDevice->SetRenderState(D3DRS_DEPTHBIAS, 0);

	//two pass:
	m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
	m_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, m_pMesh->GetNumVertices(), 0,
		m_pMesh->GetNumFaces());

	m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
	m_pD3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_DECR);
	m_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, m_pMesh->GetNumVertices(), 0,
		m_pMesh->GetNumFaces());//end draw of shadow volume

	//draw the screen rectangle that make the shadow
	m_pD3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL);
	m_pD3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
	m_pD3DDevice->SetRenderState(D3DRS_STENCILREF,  1);

	m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
	m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
	m_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
	m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);


	m_pD3DDevice->SetVertexShader(NULL);
	m_pD3DDevice->SetFVF(D3DFVF_MASKVERTEX);
	m_pD3DDevice->SetStreamSource(0, m_pMaskVertexBuffer, 0, sizeof(MASK_VERTEX));
	m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);//end draw of the screen rect

	//switch everythig back
	m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
	m_pD3DDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
	m_pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
	m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
}


And every frame I will clear out the buffer:

m_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , D3DCOLOR_XRGB(100, 100, 200), 1.0f, 0);

jhq
jhq
Nobody can help? Come on, at least give me some hints :)
Crow-knee
Crow-knee
How are you capping your shadow volume? Front or back faces of the mesh? If front, try capping with the back facing polys - i had similar results as you until i did this (dx8 though).
Hope that helps.
Steele.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.