Jump to content

  • Log In with Google      Sign In   
  • Create Account

usbman3

Member Since 19 Sep 2010
Offline Last Active Dec 05 2011 04:03 PM

#4784518 Any fast voxel rendering algorithms?

Posted by usbman3 on 11 March 2011 - 01:39 PM

I have a 3D array of voxels, which represents a landscape (sort of).

I wrote a simple function to render these voxels:

for each pixel on screen:
{
	calculate the direction and starting position of the ray
	Vec3 cur_pos = ray_start_pos
	Voxel voxel = Nothing
	
	for( temp=0; temp+=VOXEL_SIZE; temp<RAY_LENGTH )
	{
		voxel = get_voxel( cur_pos );
		
		if ( voxel != Nothing )
			break;

		cur_pos += ray_direction * VOXEL_SIZE
	}
	
	if ( voxel != Nothing )
		set_pixel( voxel.r, voxel.g, voxel.b );
	else
		set_pixel( background color );
}

Rendering 80x80x100 (=640k) voxels at resolution 700x444, it takes about 20 seconds to render one frame (on AMD Phenom II X6 @ 3.4 GHz).

Although I'm using just one thread for rendering, the performance is absolutely unacceptable! I need at least 25 frames per second.

And this algorithm has some other problems than performance as well:
  • Aliasing artifacts
  • Some voxels are processed twice
  • Lots of empty voxels are processed even if the ray doesn't hit anything
I have searched the internet but I didn't find any good articles about rendering voxels that don't involve octrees or cuda.

So, do you know of any good voxel rendering algorithms?


#591669 3D texture coordinate generation doesn't work as expected, need some help

Posted by usbman3 on 29 December 2010 - 10:47 AM

EDit: Problem has been solved. Don't bother reading this thread.

I need to render some textured axis aligned cubes. Currently I'm using a 2D texture.
I want to use a 3D texture and let OpenGL automatically generate texture coordinates, to simplify things a bit.

I have some code to generate a 2x2x2 checker pattern and then render cubes with it:

#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <GL/gl.h>

#include "image.h"
#include "checkers3d.h"

GLuint make_3d_checkers( GLubyte color1[3], GLubyte color2[3] )
{
GLuint tex;
uint8_t pixels[8*3];

/*
color1, color2,
color2, color1,
color2, color1,
color1, color2
*/


memcpy( pixels, color1, 3 );
memcpy( pixels+3, color2, 3 );
memcpy( pixels+6, color2, 3 );
memcpy( pixels+9, color1, 3 );
memcpy( pixels+12, color2, 3 );
memcpy( pixels+15, color1, 3 );
memcpy( pixels+18, color1, 3 );
memcpy( pixels+21, color2, 3 );

glGenTextures( 1, &tex );
glBindTexture( GL_TEXTURE_3D, tex );

glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT );
glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT );

// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

// apply color and lighting effects to texture
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );

// upload texture
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glTexImage3D( GL_TEXTURE_3D, 0, 3, 2, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels );

return tex;
}





static void draw_map_3d( void )
{
glEnable( GL_TEXTURE_GEN_S );
glEnable( GL_TEXTURE_GEN_T );
glEnable( GL_TEXTURE_GEN_R );
GLenum mode = GL_OBJECT_LINEAR;
glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, mode );
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, mode );
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, mode );

glEnable( GL_TEXTURE_3D );

int n;
Box *b;
static GLuint tex = 0;

if ( tex == 0 )
{
GLubyte color1[3] = {DARK};
GLubyte colo2[3] = {BRIGHT};
tex = make_3d_checkers( color1, colo2 );
}

glBindTexture( GL_TEXTURE_3D, tex );
for( n=0; n<map.num_boxes; n++ )
{
b = &map.boxes[n];

glPushMatrix();
glTranslatef( b->centre[0], b->centre[1], b->centre[2] );
glScalef( b->size[0], b->size[1], b->size[2] );
glMatrixMode( GL_TEXTURE );
glLoadIdentity();
glTranslatef( b->centre[0], b->centre[1], b->centre[2] );
glScalef( b->size[0], b->size[1], b->size[2] );
glMatrixMode( GL_MODELVIEW );
glutSolidCube( 2.0f );
glPopMatrix();
}

glMatrixMode( GL_TEXTURE );
glLoadIdentity();
glMatrixMode( GL_MODELVIEW );

glDisable( GL_TEXTURE_3D );
glDisable( GL_TEXTURE_GEN_S );
glDisable( GL_TEXTURE_GEN_T );
glDisable( GL_TEXTURE_GEN_R );
}





But texture coordinates aren't generated correctly for Z axis

<image removed>

What am I doing wrong?

[Edited by - usbman3 on December 30, 2010 9:44:30 AM]


#590190 glDrawPixels draws only garbage. Need some help.

Posted by usbman3 on 11 December 2010 - 09:49 AM

Edit: Problem solved. Don't bother reading this thread.

I have all printable ASCII characters in this picture, excluding empty space:


I converted it to raw binary:
convert font2.png -size 1128x16 -depth 8 RGBA:font.dat

Then I wrote some code to load and display that font:

static uint8_t **pixels = NULL;
static const uint16_t font_w = 1128;
static const uint16_t font_h = 16;
static const uint16_t char_w = 12;

static int read_pixels( void )
{
FILE *fp;
int c;
size_t ch_size;

fp = fopen( "data/font.dat", "r" );

if ( !fp )
return 0;

pixels = malloc( sizeof(uint8_t*) * 95 );
ch_size = font_h * char_w * 4;

for( c=0; c<95; c++ )
{
pixels[c] = malloc( ch_size );
fseek( fp, SEEK_SET, c*ch_size );
fread( pixels[c], ch_size, 1, fp );
}

fclose( fp );
return 1;
}

int load_font( void )
{
printf( "Loading font...\n" );

if ( !read_pixels() )
return 0;

return 1;
}

void draw_text( int x, int y, char *str )
{
char *c;
int index;

for( c=str; *c; c++ )
{
if ( *c == ' ' )
{
x++;
continue;
}

if ( !isprint(*c) )
index = 32;
else
index = (*c) - 32;

if ( index < 0 || index > 127 )
index = 32;

glWindowPos2i( x++ * char_w, y );
glDrawPixels( char_w, font_h, GL_RGBA, GL_UNSIGNED_BYTE, pixels[index] );
}
}


There are 2 problems with draw_text(). It draws the text at wrong coordinates, and the text looks like this:

Above should read "Hello world!" (the space shows as green background color because it is not drawn).

Do you see the problem in my code?

[Edited by - usbman3 on December 12, 2010 10:06:10 AM]


PARTNERS