• Create Account

# _undex

Member Since 18 Oct 2012
Offline Last Active Yesterday, 06:11 AM

### Performance of an experimental SVO raycaster

21 September 2015 - 05:24 PM

Hi folks

I've made a GPU-raycaster based of bcmpinc's algorithm: https://bcmpinc.wordpress.com/. In this pdf, he/she descibes how it works: https://app.box.com/s/rxvvymcz4nfygvs6fz7a.

I used HLSL and DirectCompute for the computation. So here is what I've come up with:

```#define I1 1.0f

//trace order indices:
//the algorithm begins with the voxel 000
//than it looks at the voxels 010,001 or 100,001, depending on the direction of the ray
//etc
const uint start[5] = { 0, 1, 3, 5, 6 };
const uint indices1[6] = { B_0000, B_0100, B_0001, B_0101, B_0110, B_0111 };
const uint indices2[6] = { B_0000, B_0010, B_0001, B_0011, B_0110, B_0111 };

...

//_n is a stack of pointers to the visited voxels
//_x is a float2 stack, which stores the ray plane intersections.
//the voxel planes are parallel to the current cubemap side
//_now is a stack of uint, that indicate which voxels are already traversed by the algorithm
//dir is a float2 that stores the direction of the ray
iter = 0;
while (depth != -1)
{
++iter;
//safety first
if(iter == 200)
{
return float4(0.0f,0.0f,1.0f,1.0f);
}
if (isLeaf(_n[depth]))
{
return float4(iter/64.0f, 0, iter > 100 ? 1.0f : 0.0f, 1);
}
if (_now[depth] == 4)
{
//pop stack
--depth;
}
else
{
//goto all next voxels
bool found = false;
for (uint i = start[_now[depth]]; i < start[_now[depth] + 1]; ++i)
{
//get index of the next voxel
uint trace = _x[depth].x * dir.y < _x[depth].y * dir.x ? indices1[i] : indices2[i];						//get intersections with voxel
_x[depth + 1] = ((trace & B_0001 ? _x[depth] : (_x[depth] - dir)) * 2.0f)
+ float2((trace & B_0010) ? -I1 : I1, (trace & B_0100) ? -I1 : I1);
//if ray intersects voxel
if(_x[depth + 1].x >= -I1 && _x[depth + 1].y >= -I1 && _x[depth + 1].x - 2.0f * dir.x < I1 && _x[depth + 1].y - 2.0f * dir.y < I1)
{
//get pointer to next voxel
uint ne = getChild(_n[depth], trace, flip, rot);
if (!isNothing(ne))
{
//traverse to next set of voxels
++(_now[depth]);
//push stack
++depth;
_n[depth] = ne;
//start at first voxel
_now[depth] = 0;
found = true;
break;
}
}
}
if (!found)
{
//traverse to next set of voxels
++(_now[depth]);
}
}
}
return float4(iter/64.0f, 0, iter > 100 ? 1.0f : 0.0f, 1);```

This algorithm projects the octree on a cubemap. This cubemap will then get rendered to the screen.

I also use the original algorithm to raycast with lower resolution on the cpu and use the output as a starting point for the pixels on the GPU.

The problem is, even with a octree depth of 7, I get low framerates, especially if the camera is close to and facing the surface, because a lot of pixels are hitting voxels. Also pretracing with lower resolution doesn't really help. I get the same framerates with and without this acceleration structur. Is there some major optimization I forgotten? How do these guys https://www.youtube.com/watch?v=ca7xcP3-c18 https://www.youtube.com/watch?v=km0DpZUgvbg get such a good performance? In fact this raycaster should perform better as ordinary ones, as the algorithm I use only approximates cubes. From a far one shouldn't notice that.

Here are some pictures of the raycaster:

Here is a picture without optimization:

The amount of red is porportional to the number of iterations per pixel. If a pixel exceeds 100 iterations, it turn purple.
Here is a picture with the acceleration structur:

### Geometry shader with stream output

16 February 2013 - 04:36 PM

Hello folks,

I tried to generate a stream output with a geometry shader.
But when I "draw" it, the window turns black.
Could someone show me some sample code on geometry shader with stream out or could someone correct my existing code?

Draw call:

```bool GeometrySh::Render(ID3D11DeviceContext* deviceContext, int count)
{
HRESULT result;
D3D11_MAPPED_SUBRESOURCE mappedResource;
unsigned int bufferNumber;
BufferType* dataPtr;

result = deviceContext->Map(m_cBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if(FAILED(result))
{
return false;
}

dataPtr = (BufferType*)mappedResource.pData;
dataPtr->lightdir = D3DXVECTOR4(4.0f, 5.0f, 10.0f, 1.0f);
deviceContext->Unmap(m_cBuffer, 0);

bufferNumber = 0;

deviceContext->GSSetConstantBuffers(bufferNumber, 1, &m_cBuffer);

unsigned int stride;
unsigned int offset;

stride = sizeof(VertexType);
offset = 0;

deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

deviceContext->IASetInputLayout(m_gslayout);

deviceContext->SOSetTargets(1, &m_outBuffer, &offset);

deviceContext->DrawIndexed(count, 0, 0); // If I disable this line that bug dosen't occur

ID3D11Buffer* pBuffer[1];
pBuffer[0] = NULL;
deviceContext->SOSetTargets(1, pBuffer, &offset);

return true;
}
```

```cbuffer BufferConType
{
float4 lightdir;
}

struct GIN
{
float4 pos : POSITION;
float2 tex : TEXCOORD0;
float3 normal : NORMAL;
};

struct GOUT
{
float4 pos : POSITION;
};

[maxvertexcount(3)]
void GS(triangleadj GIN input[6], inout TriangleStream<GOUT> OutputStream)
{
GOUT p;
p.pos = input[0].pos;
p.pos.w = 1.0f;
OutputStream.Append(p);
p.pos = input[2].pos;
p.pos.w = 1.0f;
OutputStream.Append(p);
p.pos = input[4].pos;
p.pos.w = 1.0f;
OutputStream.Append(p);
OutputStream.RestartStrip();
}
```

14 February 2013 - 05:06 AM

hello folks,

I keep getting an access violation exception when I create a pixelshader.

Here's the code:

```        HRESULT result;
ID3D10Blob* errorMessage;
D3D11_INPUT_ELEMENT_DESC polygonLayout[2];
unsigned int numElements;
D3D11_BUFFER_DESC matrixBufferDesc;

// Initialize the pointers this function will use to null.
errorMessage = 0;

result = D3DX11CompileFromFile(vsFilename, NULL, NULL, "VSTex", "vs_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL,

if(FAILED(result))
{
// If the shader failed to compile it should have writen something to the error message.
if(errorMessage)
{
}
// If there was nothing in the error message then it simply could not find the shader file itself.
else
{
MessageBox(hwnd, vsFilename, L"Missing Shader File", MB_OK);
}

return false;
}

// Compile the pixel shader code.
result = D3DX11CompileFromFile(psFilename, NULL, NULL, "PSTex", "ps_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL,
if(FAILED(result))
{
// If the shader failed to compile it should have writen something to the error message.
if(errorMessage)
{
}
// If there was nothing in the error message then it simply could not find the file itself.
else
{
MessageBox(hwnd, psFilename, L"Missing Shader File", MB_OK);
}

return false;
}
// Create the vertex shader from the buffer.
if(FAILED(result))
{
return false;
}
// Create the pixel shader from the buffer.
if(FAILED(result))
{
return false;
}
```

I also checked if pixelShaderBuffer is still a nullpointer but it isn't and the buffersize is a non zero value.
I hope someone can help me. I also wish you a great valentine's day.

### Geometry shader with stream output

11 February 2013 - 03:55 AM

Hi folks,

I've been trying to generate shadow volumes with the gpu.
But can't get the geometry shader to produce output.
So how can I create a shader with stream output in slimdx? Can you give me an example with code in hlsl and slimdx?

### Problem by creating texture3d out of a texture2d array

12 December 2012 - 09:46 AM

Hello folks

I use SlimDx and I'm trying to create a texture3d object out of a texture2d array.
Each texture2d object has a height and a width of the variable "scale" and there are "scale" texture2d objects in the array.
But there is a problem. I can't get the data out of that array to write it into that texture3d object. So the texture3d object is always black when I draw it.
Here's my code:

[source lang="csharp"] byte[] data = new byte[textures.Length * scale * scale * 16]; for (int i = 0; i < textures.Length; i++) { System.IO.Stream stream = System.IO.Stream.Null; Texture2D.ToStream(device.ImmediateContext, textures[i], ImageFileFormat.Png, stream); stream.Read(data, i * (int)stream.Length, (int)stream.Length); } DataBox b = new DataBox(16 * scale, 16 * scale * scale, new DataStream(data, true, true)); volume = new Texture3D(device, new Texture3DDescription() { Width = scale, Height = scale, Depth = scale, MipLevels = 1, Format = SlimDX.DXGI.Format.R32G32B32A32_Float, BindFlags = BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None, Usage = ResourceUsage.Default }, b);[/source]

I hope someone can help me.

PARTNERS