voxel terrain

Post Reply
User avatar
phase
Posts: 17
Joined: Thu Dec 20, 2012 6:16 pm
Location: Хабаровск

voxel terrain

Post by phase » Sat Jan 18, 2014 2:30 pm

Программа рендера воксельной поверхности с текстурой онованной на карте высот. Объект составляется из 3d слоёв с изменяющимся альфа-каналом.
Камера управляется мышью, колесо мыши регулирует высоту объекта.

Code: Select all

//3d layers v121
hmap_filename=file_dialog("set heightmap","gif/png/jpg","3d layer_files")
texture_filename=file_dialog("set texture","gif/png/jpg","3d layer_files")
if hmap_filename<0||texture_filename<0 {halt}
hmap=load(hmap_filename)
texture=load(texture_filename)
resize(texture,get_xsize(hmap),get_ysize(hmap),PIXEL,RESIZE_COLOR_INTERP2)
alpha=clone(hmap) 

//Set perspective matrix:
matrix = new( 4, 4, FLOAT )
clean( matrix )
t_reset()
t_get_matrix( matrix )
matrix[ 2 * 4 + 3 ] = -0.001
t_set_matrix( matrix )
t_rotate(60,1,0,0)
t_push_matrix() 

fn threshold( $img, $t)
{
op_cn(OP_GREATER,$img, $t )
op_cn(OP_MUL,$img,WHITE )
}

h=64
fn layers($h) {
t_push_matrix() 
 i=0 c=0
while(i!=$h)
{
remove(alpha)
alpha=clone(hmap)
c=255/$h*i 
threshold( alpha, get_color(c,c,c))
convert_type(alpha,INT8)
set_alpha(texture,alpha)
t_translate(0,0,1)
pixi(texture)
i+1
}
t_pop_matrix()
 }
layers()

start:

while( get_event() )
{rot=0 
    if EVT[ EVT_TYPE ] == EVT_MOUSEBUTTONDOWN 
	{ click = 1
	x0 = EVT[ EVT_X ] az0=az
	y0 = EVT[ EVT_Y ] ax0=ax
	}
    if EVT[ EVT_TYPE ] == EVT_MOUSEBUTTONUP {click = 0}
    if click && EVT[ EVT_TYPE ] == EVT_MOUSEMOVE 
	{ rot = 1 
	x = EVT[ EVT_X ]
	y = EVT[ EVT_Y ]
	az =az0+(x-x0)
	ax =ax0+(y-y0)
	}
    if EVT[ EVT_TYPE ] == EVT_QUIT 
{ save(0,"img.png",FORMAT_PNG) halt }
    if rot && ( EVT[ EVT_KEY ] == KEY_MOUSE_LEFT )
	{
	//t_reset()
	t_pop_matrix()
	t_push_matrix() 
	t_rotate(ax,1,0,0) 
	t_rotate(az,0,0,1)
	}
    if EVT[EVT_KEY]==KEY_MOUSE_SCROLLUP {h+1}
    if h>0&&EVT[EVT_KEY]==KEY_MOUSE_SCROLLDOWN {h-1}
}
clear() layers(h)
frame()
go start
Примеры текстуры и карты высот:
Image
Image
Результат:
Image
p.s. Почему-то никак не получается обработать функцией thresold 8 битный альфа-канал, при всех значениях порога результат одинаковый.Приходится преобразовывать в 32bit.
p.p.s В дальнейшем попробую raycasting реализовать.

Post Reply