Reputation: 1388
I am creating a voxel engine. I have created chunk generation in addition to some simple simplex noise integration but it is extremely laggy due to all of the face of each quad being drawn even the ones you can't see.
To my understanding this is commonly dealt with using ray casting of which I understand the basic theory: you draw several rays from the camera and check for collision, if no collision is found then the face is not within view and therefor should not be rendered. Even though I understand the theory of it all I haven't yet been able to implement it due to lack of prior knowledge and what I found on the internet lacking i.e. they give the code but not the knowledge.
The steps I could imagine I need to take are as follows:
Could anyone point me in the right direction? I also believe that there are pure OpenGL implementations as well but I would like to keep the OpenCL aspect as this is a learning experience.
Upvotes: 0
Views: 519
Reputation: 11910
Learn OpenCL (though I haven't used it before to my understanding it allows you to better make use of your graphics card by the use of 'kernels' which I mentally associate with OpenGL 'shaders').
Amd app sdk has many examples/samples from sorting numbers to doing 3d-fluid calculations on a teapot. You can also use cpu with opencl but multiple cpus can bee seen as single device. Also Nvidia and jocl and lwjgl has samples waiting to be reverese-engineered.
Learn the theory and math behind Ray casting. I have also have heard of ray tracing which I believe has a different use
I only know that ray casting becomes a tracing if those rays cast new rays. Lots of vector algebra like cross products, dot products, normalizations of direction vectors, 3x3 4x4 matrix multiplications and many more. Higher order recursivity is bad for gpu. Try with iterative versions.
Learn how to use this information to not render hidden faces.
You can sort the distances of surface primitives that a ray intersecs and get the smallest distance one. Others shouldnt be seen if there is no refraction on that surface. Using an acceleration structure (bounded bolume hierarchy,..) helps.
The cube is one object and to the best of my knowledge there is no way to manipulate the faces of an object in OpenGL only the vertices.
Generate in opencl, pass it to opengl, faster than immediate mode.
Also how would OpenCL communicate with OpenGL? OpenCL isn't a graphics api so it isn't capable of drawing the rays.
Create the context with "sharing" properties to be able to use gl-cl "interop". This enables opencl-opengl communication get as fast as gpu-vram (300 GB/s for high end). Then use gl buffers as cl buffers in this context with proper synchronizations between cl and gl.(glFinish() compute() clFinish() drawArrays())
If it is not interop then communications will be as slow as pci-e bandwidth. Then generating from cpu becomes faster if compute to data ratio is low.
If there are multiple gpus to play with, then you should pack your data as short as possible. Check endianness, alignment of structures. Dont forget to define opencl(device)-side structures if there are any in host side and they must be 1-1 compatible.
Upvotes: 0
Reputation: 795
I wouldn't recommend working with OpenCL or OpenGL in developing your first game, both will slow you down extraordinarily because each requires a different mindset. Well done though on getting as far as you have.
You mentioned that you are currently rendering all quads all the time which you want to remove hidden ones. I have written a voxel engine for practice too and ran into this issue and spent a lot of time thinking how to fix it. My solution was to not draw faces that are facing another voxel.
Imagine two voxels next to each other, the two faces that are touching cant be seen and don't need to be rendered.
However, this will not make any difference if your method of talking with the GPU is the bottleneck. You will have to use buffered methods, I used Display Lists but it is also possible (but harder) to use VBOs.
I'd also recommend grouping large numbers of voxels into chunks for many reasons. Then you only need to recalculate the visible quads on the chunk that changed.
Regarding Ray Casting, If you adopt the chunk system I just described calculating visible entire chucks will be easier. E.g Chunks behind the player don't need to be rendered and that can be calculated with just one dot product calculation per chunk.
Upvotes: 1