Jump to content
  • Advertisement
Sign in to follow this  

Voxelization goes wrong

This topic is 1468 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



I'm (again), trying to set up a voxelization pass for the scene, but the output isnt really as I imagined it to be:


Voxel Debug: ( Just splatting the colors of the voxels upon the scene )



I'm slightly suspicious about the projection matrix being the fault:

	snappedGridPositions[0] = D3DXVECTOR4(0, 0, 0, 0);
	snappedGridPositions[1] = D3DXVECTOR4(0, 0, 0, 0);
	gridPositions[0] = snappedGridPositions[0];
	gridPositions[1] = snappedGridPositions[1];

	gridCellSizes.x = 16.0f / 16.0f;
	gridCellSizes.y = 1.0f / gridCellSizes.x;
	gridCellSizes.z = 16.0f / 16.0f;
	gridCellSizes.w = 1.0f / gridCellSizes.z;

	// Temp Matrices
	D3DXMATRIX pos, rot;
	D3DXVECTOR3 vpos;

	// Generate View Matrix
		vpos = (-(D3DXVECTOR3(snappedGridPositions[0])) - D3DXVECTOR3(0.0f, 0.0f, 16));
		D3DXMatrixTranslation(&pos, vpos.x, vpos.y, vpos.z);
		mBF = pos;
		D3DXMatrixTranspose(&mBF, &mBF);

	// Generate View Matrix
		vpos = (-(D3DXVECTOR3(snappedGridPositions[0])) - D3DXVECTOR3(16, 0.0f, 0));
		D3DXMatrixTranslation(&pos, vpos.x, vpos.y, vpos.z);
		D3DXMatrixRotationAxis(&rot, &D3DXVECTOR3(0, 1, 0), 90);
		mRL = rot * pos;
		D3DXMatrixTranspose(&mRL, &mRL);

	// Generate View Matrix
		vpos = (-(D3DXVECTOR3(snappedGridPositions[0])) - D3DXVECTOR3(0, 16, 0));
		D3DXMatrixTranslation(&pos, vpos.x, vpos.y, vpos.z);
		D3DXMatrixRotationAxis(&rot, &D3DXVECTOR3(1, 0, 0), 90);
		mTD = rot * pos;
		D3DXMatrixTranspose(&mTD, &mTD);

	// Generate Proj Matrix
	D3DXMatrixOrthoLH(&mProj, 200, 200, 0.2f, 2.0f*16.0f);
	/*mProj = D3DXMATRIX(
		2.0f/(16.0f - (-16.0f)), 0, 0, 0,
		2.0f/(16.0f - (-16.0f)), 1, 0, 0,
		0, 1.0f/(0.2f - 2.0f*16.0f), 1, (-16.0f + 16.0f)/(-16.0f - 16.0f), 
		(16.0f + -16.0f) / (-16.0f - 16.0f), 0.2f / (0.2f - 2.0f*16.0f), 0, 1
	D3DXMatrixTranspose(&mProj, &mProj);

Then I use the view matrix based on what view index is most visible: ( A section of this is from a sample )

static float3 viewDirections[3] = {
	float3(0.0f, 0.0f, -1.0f), // back to front
	float3(-1.0f, 0.0f, 0.0f), // right to left
	float3(0.0f, -1.0f, 0.0f) }; // top to down 

int GetViewIndex(in float3 normal)
	float3x3 directionMatrix;
	directionMatrix[0] = -viewDirections[0];
	directionMatrix[1] = -viewDirections[1];
	directionMatrix[2] = -viewDirections[2];
	float3 dotProducts = abs(mul(directionMatrix, normal));
		float maximum = max(max(dotProducts.x, dotProducts.y), dotProducts.z);
	int index = 0;
	if (maximum == dotProducts.x)
		index = 0;
	else if (maximum == dotProducts.y)
		index = 1;
		index = 2;
	return index;

void ApplyVP(inout float4 ps, int index, float4 pos)
	if (index == 0)
		ps = mul(pos, mul(mTD, mProj));
	if (index == 1)
		ps = mul(pos, mul(mRL, mProj));
	if (index == 2)
		ps = mul(pos, mul(mBF, mProj));

void GShader(triangle VOut input[3], inout TriangleStream<GOut> outputStream)
	float3 faceNormal = normalize(input[0].normalWS + input[1].normalWS + input[2].normalWS);

		// Get view, at which the current triangle is most visible, in order to achieve highest
		// possible rasterization of the primitive.
		int viewIndex = GetViewIndex(faceNormal);

	GOut output[3];
	for (int i = 0; i < 3; i++)
		output[i] = GVertexCopy(input[i]);
		ApplyVP(output[i].positionPS, viewIndex, float4(input[i].positionWS.xyz, 1));

	// Bloat triangle in normalized device space with the texel size of the currently bound 
	// render-target. In this way pixels, which would have been discarded due to the low 
	// resolution of the currently bound render-target, will still be rasterized.
	float2 side0N = normalize(output[1].positionPS.xy - output[0].positionPS.xy);
	float2 side1N = normalize(output[2].positionPS.xy - output[1].positionPS.xy);
	float2 side2N = normalize(output[0].positionPS.xy - output[2].positionPS.xy);

	float texelSize = 1.0f / 64.0f;

	output[0].positionPS.xy += normalize(-side0N + side2N)*texelSize;
	output[1].positionPS.xy += normalize(side0N - side1N)*texelSize;
	output[2].positionPS.xy += normalize(side1N - side2N)*texelSize;

	for (int j = 0; j < 3; j++)


Then the voxel position is found as following:

int GetGridIndex(in int3 position)
	return ((position.z * 1024) + (position.y * 32) + position.x);

	float3 offset = (input.positionWS - snappedGridPositions[0].xyz)*gridCellSizes.y;
		offset = round(offset);

	if ((voxelPos.x>-1) && (voxelPos.x<32) && (voxelPos.y>-1) && (voxelPos.y<32) && (voxelPos.z>-1) && (voxelPos.z<32))
		// get index into the voxel-grid
		int gridIndex = GetGridIndex(voxelPos);

Then the last step, debugging the actual voxels is done as following:

float depth = t_depthX.Sample(ss, input.Tex);
	float3 viewRay = normalize(input.ViewRay);
	float3 positionWS = cameraPosition + viewRay * depth;

	if (depth == 0) discard;

	// find for the current pixel best voxel representation
	float3 offset = (positionWS.xyz - snappedGridPositions[0].xyz)*gridCellSizes.y;
	float dist = length(offset);

	float3 color = float3(0, 0, 0);

		// get index of current voxel
		offset = round(offset);
		int3 voxelPos = int3(16, 16, 16) + int3(offset.x, offset.y, offset.z);
		if ((voxelPos.x<0) || (voxelPos.x>31) || (voxelPos.y<0) || (voxelPos.y>31) || (voxelPos.z<0) || (voxelPos.z>31))
			return float4(1,0,0,1);

I understand that this is a big chunk of code, but I've repeatedly been looking through it and failed to find the error, so any help at all would be appreciated.



Edited by Migi0027

Share this post

Link to post
Share on other sites

... I've repeatedly been looking through it and failed to find the error, ...

well, looking at code is the least likely way to find bugs. you need to debug it, you need to validate parts of it, compare expected vs real results and reduce the area of error to as few bits of code as possible. programming consists of a big part of debugging and the more efficient you'll do that, the faster you'll make progress. it might sound like some work to create those validations, but it's a deterministic way to find bugs, rather than looking at code which might kill the bug in a minute or might never kill it.

also, there might be multiple errors and fixing one possible bug might not lead you to proper result and without validation, how would you really be sure it's as it should be? also, bugs will re-appear for as long as you work on your code. having a way to validate parts of it will save you tons of time in the future, you might even catch bugs that you wouldn't be aware of for a long time and later on you might have been searching in a big code base.

so, sorry, but improve your debugging skills. you have an input -> blackbox -> wrong output. slice the blackbox into smaller parts, find the error line. you will not even need us to fix that line, probably, but if you need our help, you'll be able to post the critical part and we'll give you more accurate suggest.

Share this post

Link to post
Share on other sites

Thank you.


My debugging skills are no where near where they should be, so I tried taking your advice to find the problem.


Actually the problem turned out to be that I forgot to apply the world matrix when voxelising resulting in the scales being way off.



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!