BMAP* canvas;
ENTITY* p_terrain;
var canvas_size[2];
var shadow_brightness=112;
//-----------------------------------------------------------------------------blur
function blur(passes)
{
var i;
var px;
var py;
var format;
var pixel;
var pixelcolor[3];
var pixelalpha;
var sample1[3];
var sample2[3];
var sample3[3];
var sample4[3];
var sample5[3];
var sample6[3];
var sample7[3];
var sample8[3];
var sample9[3];
i=0;
while(i<passes)
{
py=0;
while(py < canvas_size[1])
{
px=0;
while(px<canvas_size[0])
{
format=bmap_lock(canvas,0);
pixel=pixel_for_bmap(canvas,clamp((canvas_size[0]-1)-px,0,canvas_size[0]-1),clamp(py,0,canvas_size[0]-1));
pixel_to_vec(sample1,pixelalpha,format,pixel);
pixel=pixel_for_bmap(canvas,clamp((canvas_size[0]-1)-px-1,0,canvas_size[0]-1),clamp(py,0,canvas_size[0]-1));
pixel_to_vec(sample2,pixelalpha,format,pixel);
pixel=pixel_for_bmap(canvas,clamp((canvas_size[0]-1)-px-1,0,canvas_size[0]-1),clamp(py+1,0,canvas_size[0]-1));
pixel_to_vec(sample3,pixelalpha,format,pixel);
pixel=pixel_for_bmap(canvas,clamp((canvas_size[0]-1)-px,0,canvas_size[0]-1),clamp(py+1,0,canvas_size[0]-1));
pixel_to_vec(sample4,pixelalpha,format,pixel);
pixel=pixel_for_bmap(canvas,clamp((canvas_size[0]-1)-px+1,0,canvas_size[0]-1),clamp(py+1,0,canvas_size[0]-1));
pixel_to_vec(sample5,pixelalpha,format,pixel);
pixel=pixel_for_bmap(canvas,clamp((canvas_size[0]-1)-px+1,0,canvas_size[0]-1),clamp(py,0,canvas_size[0]-1));
pixel_to_vec(sample6,pixelalpha,format,pixel);
pixel=pixel_for_bmap(canvas,clamp((canvas_size[0]-1)-px+1,0,canvas_size[0]-1),clamp(py-1,0,canvas_size[0]-1));
pixel_to_vec(sample7,pixelalpha,format,pixel);
pixel=pixel_for_bmap(canvas,clamp((canvas_size[0]-1)-px,0,canvas_size[0]-1),clamp(py-1,0,canvas_size[0]-1));
pixel_to_vec(sample8,pixelalpha,format,pixel);
pixel=pixel_for_bmap(canvas,clamp((canvas_size[0]-1)-px-1,0,canvas_size[0]-1),clamp(py-1,0,canvas_size[0]-1));
pixel_to_vec(sample9,pixelalpha,format,pixel);
pixelcolor[0]=integer((sample1[0]*7+sample2[0]*2+sample3[0]+sample4[0]*2+sample5[0]+sample6[0]*2+sample7[0]+sample8[0]*2+sample9[0])/19);
pixelcolor[1]=integer((sample1[1]*7+sample2[1]*2+sample3[1]+sample4[1]*2+sample5[1]+sample6[1]*2+sample7[1]+sample8[1]*2+sample9[1])/19);
pixelcolor[2]=integer((sample1[2]*7+sample2[2]*2+sample3[2]+sample4[2]*2+sample5[2]+sample6[2]*2+sample7[2]+sample8[2]*2+sample9[2])/19);
pixel=pixel_for_vec(pixelcolor,100,format);
pixel_to_bmap(canvas,(canvas_size[0]-1)-px,py,pixel);
bmap_unlock(canvas);
px+=1;
}
py+=1;
wait(1); // without a wait after each line the loop could get too big if the shadow map is huge
}
i+=1;
}
}
//-----------------------------------------------------------------------------generate_shadows
function getxyz(px,py)
{
var pixel_size[2];
pixel_size[0]=(p_terrain.max_x-p_terrain.min_x)/canvas_size[0];
pixel_size[1]=(p_terrain.max_y-p_terrain.min_y)/canvas_size[1];
temp[0]=((p_terrain.x-p_terrain.min_x)-(pixel_size[0]*px))-pixel_size[0]/2;
temp[1]=((p_terrain.y-p_terrain.min_y)-(pixel_size[1]*py))-pixel_size[1]/2;
c_trace(vector(temp[0],temp[1],p_terrain.z+50000),vector(temp[0],temp[1],p_terrain.z-50000),IGNORE_MODELS|IGNORE_SPRITES|IGNORE_MAPS);
temp[2]=target.z;
}
function generate_shadows()
{
var px;
var py;
var format;
var pixel;
py=0;
while(py<canvas_size[1])
{
px=0;
while(px<canvas_size[0])
{
getxyz(px,py); // get the world coordinates of the pixel
c_trace(sun_pos.x,vector(temp[0],temp[1],temp[2]+1),IGNORE_ME|IGNORE_SPRITES); // trace from the sun to the pixel
if(trace_hit) // draw shadow pixel if there is no obstacle
{
format=bmap_lock(canvas,0);
pixel=pixel_for_vec(vector(shadow_brightness,shadow_brightness,shadow_brightness),100,format);
pixel_to_bmap(canvas,(canvas_size[0]-1)-px,py,pixel);
bmap_unlock(canvas);
}
px+=1;
}
py+=1;
wait(1); // without a wait after each line the loop could get too big if the shadow map is huge
}
blur(1); // do 1 blur pass
}
//-----------------------------------------------------------------------------terrain
function terrain()
{
p_terrain=my;
// my.material=mtl_terrainshadowmap;
canvas=bmap_for_entity(my,2); // the second texture of the terrain is the shadowmap
canvas_size[0]=bmap_width(canvas);
canvas_size[1]=bmap_height(canvas);
wait(1);
generate_shadows();
}
//here is a simple example material. the first texture of the terrain has to be the color map (the tiling can be specified with the texture transformation matrix). the second texture of the terrain has to be the shadow map.
//-----------------------------------------------------------------------------materials
//material mtl_terrainshadowmap
//{
// effect=
// "
// texture entSkin1;
// texture entSkin2;
//
// technique one_pass_shadow
// {
// pass p0
// {
// Texture[0]=<entSkin1>;
// Texture[1]=<entSkin2>;
//
// ColorArg1[0]=Texture;
// ColorOp[0]=Modulate2x;
// ColorArg2[0]=Diffuse;
// TexCoordIndex[0]=0;
// TextureTransformFlags[0]=Count2;
// TextureTransform[0]={8.0,0.0,0.0,0.0, // color map u scale
// 0.0,8.0,0.0,0.0, // color map v scale
// 0.0,0.0,0.0,0.0,
// 0.0,0.0,0.0,0.0};
//
// ColorArg1[1]=Texture;
// ColorOp[1]=Modulate;
// ColorArg2[1]=Current;
// TexCoordIndex[1]=0;
// TextureTransformFlags[1]=Count2;
// TextureTransform[1]={1.0,0.0,0.0,0.0,
// 0.0,1.0,0.0,0.0,
// 0.0,0.0,0.0,0.0,
// 0.0,0.0,0.0,0.0};
// }
// }
// ";
//}