BMAP* canvas;
ENTITY* p_terrain;
VECTOR canvas_size;
var shadow_brightness=112;
//-----------------------------------------------------------------------------blur
void blur(passes)
{
var i;
var px;
var py;
var format;
var pixel;
VECTOR pixelcolor;
var pixelalpha;
VECTOR sample1;
VECTOR sample2;
VECTOR sample3;
VECTOR sample4;
VECTOR sample5;
VECTOR sample6;
VECTOR sample7;
VECTOR sample8;
VECTOR sample9;
i=0;
while(i<passes)
{
py=0;
while(py < canvas_size.y)
{
px=0;
while(px<canvas_size.x)
{
format=bmap_lock(canvas,0);
pixel=pixel_for_bmap(canvas,clamp((canvas_size.x-1)-px,0,canvas_size.x-1),clamp(py,0,canvas_size.x-1));
pixel_to_vec(sample1,pixelalpha,format,pixel);
pixel=pixel_for_bmap(canvas,clamp((canvas_size.x-1)-px-1,0,canvas_size.x-1),clamp(py,0,canvas_size.x-1));
pixel_to_vec(sample2,pixelalpha,format,pixel);
pixel=pixel_for_bmap(canvas,clamp((canvas_size.x-1)-px-1,0,canvas_size.x-1),clamp(py+1,0,canvas_size.x-1));
pixel_to_vec(sample3,pixelalpha,format,pixel);
pixel=pixel_for_bmap(canvas,clamp((canvas_size.x-1)-px,0,canvas_size.x-1),clamp(py+1,0,canvas_size.x-1));
pixel_to_vec(sample4,pixelalpha,format,pixel);
pixel=pixel_for_bmap(canvas,clamp((canvas_size.x-1)-px+1,0,canvas_size.x-1),clamp(py+1,0,canvas_size.x-1));
pixel_to_vec(sample5,pixelalpha,format,pixel);
pixel=pixel_for_bmap(canvas,clamp((canvas_size.x-1)-px+1,0,canvas_size.x-1),clamp(py,0,canvas_size.x-1));
pixel_to_vec(sample6,pixelalpha,format,pixel);
pixel=pixel_for_bmap(canvas,clamp((canvas_size.x-1)-px+1,0,canvas_size.x-1),clamp(py-1,0,canvas_size.x-1));
pixel_to_vec(sample7,pixelalpha,format,pixel);
pixel=pixel_for_bmap(canvas,clamp((canvas_size.x-1)-px,0,canvas_size.x-1),clamp(py-1,0,canvas_size.x-1));
pixel_to_vec(sample8,pixelalpha,format,pixel);
pixel=pixel_for_bmap(canvas,clamp((canvas_size.x-1)-px-1,0,canvas_size.x-1),clamp(py-1,0,canvas_size.x-1));
pixel_to_vec(sample9,pixelalpha,format,pixel);
pixelcolor.x=integer((sample1.x*7+sample2.x*2+sample3.x+sample4.x*2+sample5.x+sample6.x*2+sample7.x+sample8.x*2+sample9.x)/19);
pixelcolor.y=integer((sample1.y*7+sample2.y*2+sample3.y+sample4.y*2+sample5.y+sample6.y*2+sample7.y+sample8.y*2+sample9.y)/19);
pixelcolor.z=integer((sample1.z*7+sample2.z*2+sample3.z+sample4.z*2+sample5.z+sample6.z*2+sample7.z+sample8.z*2+sample9.z)/19);
pixel=pixel_for_vec(pixelcolor,100,format);
pixel_to_bmap(canvas,(canvas_size.x-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
void getxyz(px, py, VECTOR* pos)
{
VECTOR pixel_size;
pixel_size.x = (p_terrain.max_x-p_terrain.min_x)/canvas_size.x;
pixel_size.y = (p_terrain.max_y-p_terrain.min_y)/canvas_size.y;
pos.x = ((p_terrain.x-p_terrain.min_x)-(pixel_size.x*px))-pixel_size.x*0.5;
pos.y = ((p_terrain.y-p_terrain.min_y)-(pixel_size.y*py))-pixel_size.y*0.5;
c_trace(vector(pos.x, pos.y, p_terrain.z+50000), vector(pos.x, pos.y, p_terrain.z-50000), IGNORE_MODELS|IGNORE_SPRITES|IGNORE_MAPS);
pos.z=target.z;
}
void generate_shadows()
{
var px;
var py;
var format;
var pixel;
me = p_terrain;
py=0;
while(py<canvas_size.y)
{
px=0;
while(px<canvas_size.x)
{
VECTOR pos;
getxyz(px, py, pos); // get the world coordinates of the pixel
c_trace(sun_pos.x, pos, 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.x-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
void terrain(ENTITY* ent)
{
p_terrain = ent;
// my.material=mtl_terrainshadowmap;
canvas = bmap_for_entity(ent,2); // the second texture of the terrain is the shadowmap
canvas_size.x = bmap_width(canvas);
canvas_size.y = bmap_height(canvas);
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]={1.0,0.0,0.0,0.0, // color map u scale
// 0.0,1.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};
// }
// }
// ";
//}
//