Slope Blendmap Generator

Posted By: oliver2s

Slope Blendmap Generator - 12/11/13 19:43

This code generates a blendmap out of a given heightmap. The angles which defines a slope (between 0-90 degrees) can be adjusted via function parameter.



Code:
BMAP* bmap_heightmap_to_normalmap(BMAP* bmap_hmap_,BMAP* bmap_nmap_,var factor_);

//Make Blendmap from Heightmap on slopes
///////////////////////////////
// bmap_hmap_			-> heightmap
// bmap_blendmap_		-> blendmap which will be painted or NULL for creating new blendmap
// color_			-> color which will be painted in blendmap on slopes
// gradientMin_			-> angle of slopes where painting should begin (range 0-90)
// gradientMax_			-> angle of slopes where painting should stop (range 0-90)
///////////////////////////////
BMAP* bmap_heightmap_to_blendmap_slopes(BMAP* bmap_hmap_,BMAP* bmap_blmap_,COLOR* color_,var gradientMin_,var gradientMax_)
{
	//clear up gradients
	var gradient_min_=gradientMin_;
	var gradient_max_=gradientMax_;
	if(gradient_max_<gradient_min_)
	{
		gradient_max_=gradientMin_;
		gradient_min_=gradientMax_;
	}
	gradient_min_=clamp(gradient_min_,0,90);
	gradient_max_=clamp(gradient_max_,0,90);
	if(gradient_min_==gradient_max_){ return NULL; }
	
	//store color
	COLOR c1_;
	c1_.red=color_.red;
	c1_.green=color_.green;
	c1_.blue=color_.blue;
	
	//get size
	var size_x_=bmap_width(bmap_hmap_);
	var size_y_=bmap_height(bmap_hmap_);
	
	//create tmp normalmap bmap
	BMAP* normalmap_=bmap_heightmap_to_normalmap(bmap_hmap_,NULL,1);
	
	//create temp bitmap for blendmap
	BMAP* blendmap_=bmap_createblack(size_x_,size_y_,24);

	//search slopes within the given range on normalmap
	int py; for(py=0;py<size_y_;py++)
	{
		int px; for(px=0;px<size_x_;px++)
		{
			//get normalmap pixel
			COLOR c_;
			var format=bmap_lock(normalmap_,0);var alpha_;
			var pixel=pixel_for_bmap(normalmap_, px, py);
			pixel_to_vec(c_,alpha_,format,pixel);
			bmap_unlock(normalmap_);
			
			//convert normalmap pixel to normal vector
			VECTOR n;
			n.x = 2.0*(c_.red-128);
			n.y = 2.0*(c_.green-128);
			n.z = 2.0*(c_.blue-128);
			
			//normalize to 0-1
			vec_normalize(n,1);
			
			//get Euler angle
			var angle = 90-asinv(abs(n.z));
				
			//if angle is between given angles, paint blendmap
			if(angle>=gradient_min_ && angle<=gradient_max_)
			{
				//paint given color to blendmap
				var format=bmap_lock(blendmap_,0);
				var pixel=pixel_for_vec(c1_,100,format);
				pixel_to_bmap(blendmap_, px, py, pixel);
				bmap_unlock(blendmap_);
			}
		}
	}
	
	//remove tmp normalmap
	bmap_purge(normalmap_);
	bmap_remove(normalmap_);
	
	//return new created blendmap if no target bitmap was passed to function
	if(bmap_blmap_==NULL){return blendmap_;}
	else
	{
		//otherwise copy created blendmap to target bitmap
		bmap_blit(bmap_blmap_,blendmap_,NULL,vector(bmap_width(bmap_blmap_),bmap_height(bmap_blmap_),0));
		
		//delete temp bitmap
		bmap_purge(blendmap_);
		bmap_remove(blendmap_);
		
		//return
		return bmap_blmap_;
	}
}

BMAP* bmap_heightmap_to_normalmap(BMAP* bmap_hmap_,BMAP* bmap_nmap_,var factor_)
{		
	//get size
	var size_x_=bmap_width(bmap_hmap_);
	var size_y_=bmap_height(bmap_hmap_);
	
	BMAP* normalmap_=bmap_createblack(size_x_,size_y_,24);
	
	int py; for(py=0;py<size_y_;py++)
	{
		int px; for(px=0;px<size_x_;px++)
		{
			//get height of 3 neighbor pixels
			COLOR color_;
			var c1,c2,c3;
			var format=bmap_lock(bmap_hmap_,0);var alpha_;
			var pixel=pixel_for_bmap(bmap_hmap_, clamp(px-1,0,size_x_), clamp(py-1,0,size_y_));
			pixel_to_vec(color_,alpha_,format,pixel); c1=color_.red;
			var pixel=pixel_for_bmap(bmap_hmap_, clamp(px+1,0,size_x_), clamp(py-1,0,size_y_));
			pixel_to_vec(color_,alpha_,format,pixel); c2=color_.red;
			var pixel=pixel_for_bmap(bmap_hmap_, clamp(px-1,0,size_x_), clamp(py+1,0,size_y_));
			pixel_to_vec(color_,alpha_,format,pixel); c3=color_.red;
			bmap_unlock(bmap_hmap_);

			//build temporary points that makes a triangle
			VECTOR v1,v2,p1,p2,p3;
			p1.x=0;p1.y=0;p1.z=c1*factor_;
			p2.x=32;p2.y=0;p2.z=c2*factor_;
			p3.x=0;p3.y=32;p3.z=c3*factor_;
			
			//get first vector for cross product (p2-p1)
			v1.x=p2.x-p1.x;
			v1.y=p2.y-p1.y;
			v1.z=p2.z-p1.z;
			
			//get second vector for cross product (p3-p1)
			v2.x=p3.x-p1.x;
			v2.y=p3.y-p1.y;
			v2.z=p3.z-p1.z;
			
			//calculate cross product of v1 and v2
			VECTOR n;
			vec_cross(n,v1,v2);
			
			//normalize to color range 0-255
			vec_normalize(n,255);
			
			//convert vector into normalmap color
			n.x=n.x/2 + 128;
			n.y=n.y/2 + 128;
			n.z=n.z/2 + 128;
			
			//copy color
			COLOR color1_;
			color1_.red=n.x;
			color1_.green=n.y;
			color1_.blue=n.z;
			
			//get height of another 3 neighbor pixels
			COLOR color_;
			var c1,c2,c3;
			var format=bmap_lock(bmap_hmap_,0);var alpha_;
			var pixel=pixel_for_bmap(bmap_hmap_, clamp(px+1,0,size_x_), clamp(py+1,0,size_y_));
			pixel_to_vec(color_,alpha_,format,pixel); c1=color_.red;
			var pixel=pixel_for_bmap(bmap_hmap_, clamp(px-1,0,size_x_), clamp(py+1,0,size_y_));
			pixel_to_vec(color_,alpha_,format,pixel); c2=color_.red;
			var pixel=pixel_for_bmap(bmap_hmap_, clamp(px+1,0,size_x_), clamp(py-1,0,size_y_));
			pixel_to_vec(color_,alpha_,format,pixel); c3=color_.red;
			bmap_unlock(bmap_hmap_);

			//build temporary points that makes a triangle
			VECTOR v1,v2,p1,p2,p3;
			p1.x=32;p1.y=32;p1.z=c1*factor_;
			p2.x=0;p2.y=32;p2.z=c2*factor_;
			p3.x=32;p3.y=0;p3.z=c3*factor_;
			
			//get first vector for cross product (p2-p1)
			v1.x=p2.x-p1.x;
			v1.y=p2.y-p1.y;
			v1.z=p2.z-p1.z;
			
			//get second vector for cross product (p3-p1)
			v2.x=p3.x-p1.x;
			v2.y=p3.y-p1.y;
			v2.z=p3.z-p1.z;
			
			//calculate cross product of v1 and v2
			VECTOR n;
			vec_cross(n,v1,v2);
			
			//normalize to color range 0-255
			vec_normalize(n,255);
			
			//convert vector into normalmap color
			n.x=n.x/2 + 128;
			n.y=n.y/2 + 128;
			n.z=n.z/2 + 128;
			
			//copy color
			COLOR color2_;
			color2_.red=n.x;
			color2_.green=n.y;
			color2_.blue=n.z;
			
			COLOR color_;
			color_.red=(color1_.red+color2_.red)/2;
			color_.green=(color1_.green+color2_.green)/2;
			color_.blue=(color1_.blue+color2_.blue)/2;
			
			//add to pixels
			var format=bmap_lock(normalmap_,0);
			var pixel=pixel_for_vec(color_,100,format);
			pixel_to_bmap(normalmap_, px, py, pixel);
			bmap_unlock(normalmap_);
		}
	}
	
	//return new created Normalmap if no target bitmap was passed to function
	if(bmap_nmap_==NULL){return normalmap_;}
	else
	{
		//otherwise copy created Normalmap to target bitmap
		bmap_blit(bmap_nmap_,normalmap_,NULL,vector(bmap_width(bmap_nmap_),bmap_height(bmap_nmap_),0));
		
		//delete temp bitmap
		bmap_purge(normalmap_);
		bmap_remove(normalmap_);
		
		//return
		return bmap_nmap_;
	}
}



All scripts to make a terrain like in the screenshot above:

1. Combine a Perlin Noise Heightmap of 2/3 with a Voronoi Heightmap of 1/3
2. Use the Perturbation Filter over the combined heightmap.
3. Run the Hydralic Erosion Script over the heightmap.
4. Blur it a litte bit (had no script yet for this, made this in Photoshop)
Posted By: gri

Re: Slope Blendmap Generator - 12/12/13 11:25

nice work.
Posted By: PadMalcom

Re: Slope Blendmap Generator - 12/12/13 14:49

Awesome! Those heightmaps are the most useful because you can even place buildings on the flat areas.
Posted By: oliver2s

Re: Slope Blendmap Generator - 12/12/13 15:12

Yes, I'm happy I found that paper where those heightmap algorithm was featured. But I had to blur the final heightmap result, because the cliffs were too sharp.
Posted By: lemming

Re: Slope Blendmap Generator - 12/12/13 17:36

Thank you for your contributions! The are awesome and very very useful!
Posted By: Superku

Re: Slope Blendmap Generator - 12/12/13 19:16

I really like the mesh of the terrain from the screenshot (in terms of usability for video games)!
However, I think the terrain really needs triplanar texture mapping, the stretched texture on the slopes if not up to date.

Btw. just saw the following part of your code:

Code:
VECTOR n;
n.x = 2.0*(c_.red-128);
n.y = 2.0*(c_.green-128);
n.z = 2.0*(c_.blue-128);

//normalize to 0-1
vec_normalize(n,1);

//get Euler angle
ANGLE rotation;
vec_rotate(n,vector(0,-90,0));
vec_to_angle(rotation,n);

//if angle is between given angles, paint blendmap
if(abs(rotation.tilt)>gradient_min_ && abs(rotation.tilt)<gradient_max_)


Basically you are only interested in the z-component of the normal vector, aren't you? If it's 1 your rotation.tilt is 0, near 1 the slope is near 90° in incline. Thus you should be able to skip the whole (vec_to_)angle stuff and work with the normal vector directly.
Posted By: oliver2s

Re: Slope Blendmap Generator - 12/12/13 19:55

Originally Posted By: Superku
However, I think the terrain really needs triplanar texture mapping, the stretched texture on the slopes if not up to date.

Yes you are right. This is one thing I should work on. Never read about theory behind it, but I'm sure a google search give me dozen of papers about this.

Originally Posted By: Superku
Basically you are only interested in the z-component of the normal vector, aren't you? If it's 1 your rotation.tilt is 0, near 1 the slope is near 90° in incline. Thus you should be able to skip the whole (vec_to_)angle stuff and work with the normal vector directly.

I really suck at vector mathematics. but I think vec_to_angle is neccesary, because you need the exact euler angle. The normal vector gives you only the direction.
Posted By: Random

Re: Slope Blendmap Generator - 12/12/13 20:55

What did you use to create your terrain?
Posted By: EpsiloN

Re: Slope Blendmap Generator - 12/12/13 21:29

I think he's using his generators from the start of this series of posts... laugh

Isnt this awesome? Now we get a random map generator!
Posted By: Superku

Re: Slope Blendmap Generator - 12/13/13 04:14

Just thought about it and tested it, you can replace the vec_to_angle code with rotation_tilt = -asinv(n.z); which gives you the very same angle as with your current code but more elegant and much faster.
Posted By: sivan

Re: Slope Blendmap Generator - 12/13/13 08:04

you can find 1-2 triplanar texturing source in the forum. as I remember a shader contest winner applied multitexturing triplanar texturing to simulate a bacterium, but not 100% sure.
I have a simple triplanar texturing shader I don't remember who made it (I want to add it shadowmapping to use it for rocks and cliffs):
Code:
#define WorldToTextureScale 128.0f // number of quants per texture repeat / tile
#define ProjectionPower 2.0f // Power for the projection, compensates brightnes differences; 2 gives perfect results (makes the blending gradient spherical)

//#define UseWorldSpace // calculate pixel position in world-space instead of entity-space; only for static entities, scale and angle must be default! moving/scaling/rotating looks UGLY!

// Debugging:
//	#define DebugProjections
//

float4x4 matWorld;
float4x4 matView;
float4x4 matProj;

texture entSkin1; // Texture

sampler smpTex = sampler_state
{
	Texture = <entSkin1>;
	
	MipFilter = Anisotropic;
	MagFilter = Anisotropic;
	MinFilter = Anisotropic;
	
	AddressU = Wrap;
	AddressV = Wrap;
};

struct VertexShaderInput
{
	float4 Position : POSITION0;
	float2 Tex : TEXCOORD0;
	float3 Normal : NORMAL;
};

struct VertexShaderOutput
{
	float4 Position : POSITION0;
//	float2 Tex : TEXCOORD0; // Not needed - triplanar texture mapping only needs the pixel's position and normal
	float3 Normal : TEXCOORD1;
	float4 Pos : TEXCOORD2;
};

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
	VertexShaderOutput output;
	
	float4 worldPosition = mul(input.Position, matWorld);
	float4 viewPosition = mul(worldPosition, matView);
	output.Position = mul(viewPosition, matProj);
	
//	output.Tex = input.Tex; // Not needed - triplanar texture mapping only needs the pixel's position and normal
	
	#ifdef UseWorldSpace
		output.Pos = worldPosition; // position in world-space
	#else
		output.Pos = input.Position; // position in entity-space
	#endif
	
	output.Normal = input.Normal;
	
	return output;
}

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
	float3 PixelPos = -input.Pos.xyz / WorldToTextureScale;
	
	/*
	
	coords:
	xz - Top & Bottom (Z-Axis)
	yz - Front & Back (X-Axis)
	xy - Left & Right (Y-Axis)
	
	*/
	
	
	// calculate intensity for every projection dir \\
	
	// projection intensity - Top & Bottom:
//	float zProj = pow(abs(dot(input.Normal, float3(0.f, 1.f, 0.f))), ProjectionPower); // pow to correct the blending gradient
//	float zProj = pow(abs(input.Normal.y), ProjectionPower);	// same as above
	float zProj = input.Normal.y*input.Normal.y;					// if ProjectionPower is = 2 it is the same
	
	// projection intensity - Front & Back:
//	float xProj = pow(abs(dot(input.Normal, float3(1.f, 0.f, 0.f))), ProjectionPower); // pow to correct the blending gradient
	float xProj = input.Normal.x*input.Normal.x;	
	
	// projection intensity - Left & Right:
//	float yProj = pow(abs(dot(input.Normal, float3(0.f, 0.f, 1.f))), ProjectionPower); // pow to correct the blending gradient
	float yProj = input.Normal.z*input.Normal.z;	
	
	// project the texture from x, y and z direction \\
	
	float4 Color = float4(0, 0, 0, 1); // set Base-RGBA (0,0,0,1)
	
	Color.rgb += tex2D(smpTex, PixelPos.xz).rgb * zProj; // Z - Top, Bottom
	Color.rgb += tex2D(smpTex, PixelPos.zy + 0.33333f).rgb * xProj; // X - Front, Back; move to prevent visible seams (otherwise the result looks like mirrored at specific angles)
	Color.rgb += tex2D(smpTex, PixelPos.xy + 0.66666f).rgb * yProj; // Y - Left, Right; move to prevent visible seams (otherwise the result looks like mirrored at specific angles)
	
	#ifdef DebugProjections
		Color.rgb = float3(xProj, yProj, zProj);
	#endif
	
	return Color;
}

technique Technique1
{
	pass Pass1
	{
		AlphaBlendEnable = TRUE;
		
		VertexShader = compile vs_3_0 VertexShaderFunction();
		PixelShader = compile ps_3_0 PixelShaderFunction();
	}
}

Posted By: oliver2s

Re: Slope Blendmap Generator - 12/13/13 09:10

Originally Posted By: Random
What did you use to create your terrain?

As Epsilon said, I used a combination of the heightmaps I've posted the last days.

1. Combine a Perlin Noise Heightmap of 2/3 with a Voronoi Heightmap of 1/3
2. Use the Perturbation Filter over the combined heightmap.
3. Run the Hydralic Erosion Script over the heightmap.
4. Blur it a litte bit (had no script yet for this, made this in Photoshop)

Originally Posted By: Superku
Just thought about it and tested it, you can replace the vec_to_angle code with rotation_tilt = -asinv(n.z); which gives you the very same angle as with your current code but more elegant and much faster.

Thank you for testing. Changed the code above laugh

Originally Posted By: sivan
you can find 1-2 triplanar texturing source in the forum. as I remember a shader contest winner applied multitexturing triplanar texturing to simulate a bacterium, but not 100% sure.
I have a simple triplanar texturing shader I don't remember who made it (I want to add it shadowmapping to use it for rocks and cliffs)

Thanks for posting the code.
Posted By: 3run

Re: Slope Blendmap Generator - 12/13/13 09:17

Thank you man, it's really awesome to see some great contributions, bringing our forum alive! laugh
Originally Posted By: oliver2s
4. Blur it a litte bit (had no script yet for this, made this in Photoshop)
There was an example, how to blur a shadowmap (from the image), in mystymood. It could be useful I guess laugh


Greets
Posted By: sivan

Re: Slope Blendmap Generator - 12/13/13 10:43

yes, I use that blurrrrrer in my editor in a slightly modified form (the outer dependencies to be removed are: Map_Progressbar, map_loadpanel, map_loadbar):

Code:
// for lightmap - okay - mod
void TerEdit_Lm_Blur(var passes, BMAP* canvas, var treshold, var strength)
{
	sys_marker("b01");
	
	set( map_loadpanel , SHOW);
	wait(3);
	
	var size_x = bmap_width(canvas);
	var size_y = bmap_height(canvas);
	
	VECTOR canvas_size;
	vec_set(canvas_size,vector(size_x, size_y, 0));
	
	var i;
	var px;
	var py;
	
	var 	format;
	var 	pixel;
	var 	pixelalpha;										// not used only dummy value holder	
	COLOR pixelcolor;
	vec_set(pixelcolor,vector(128,128,128));
	
	// own color and 8 neighbours
	VECTOR sample1;
	VECTOR sample2;
	VECTOR sample3;
	VECTOR sample4;
	VECTOR sample5;
	VECTOR sample6;
	VECTOR sample7;
	VECTOR sample8;
	VECTOR sample9; 
	
	VECTOR sampleX;
	vec_set(sampleX,vector(128,128,128));
	
	sys_marker(NULL);
	
	i=0;
	for (i=0;i<passes;i++)
		{
			for (py=0;py<canvas_size.y;py++)
				{					
					format = bmap_lock(canvas,0);  
					
//					draw_text( "PRESS 'B' TO BREAK LIGHTMAP CREATION!" , 150 , 100 , vector(255,255,255) );
//					if (key_b) break;
//					wait(1);
					
					for (px=0;px<canvas_size.x;px++)
						{
							sys_marker("b01");														
//							pixel=pixel_for_bmap(canvas,clamp((canvas_size.x-1)-px,0,canvas_size.x-1),clamp(py,0,canvas_size.x-1));
							pixel=pixel_for_bmap(canvas,px,py);
							pixel_to_vec(sample1,pixelalpha,format,pixel);
							
							if ( abs(128-sample1.x) < treshold)			// (sample1.x+sample1.y+sample1.z)/3 < 128-treshold - both +/- treshold
								{
									
									sys_marker(NULL);
									sys_marker("b02");
									if (px>0)
										{
				//							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=pixel_for_bmap(canvas,px-1,py);
											pixel_to_vec(sample2,pixelalpha,format,pixel);
										}
									else
										{
											vec_set(sample2,sampleX);
										}
									
									sys_marker(NULL);
									sys_marker("b03");
									if ((px>0) && (py<canvas_size.y-2))
										{
				//							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=pixel_for_bmap(canvas,px-1,py+1);
											pixel_to_vec(sample3,pixelalpha,format,pixel);
										}
									else
										{
											vec_set(sample3,sampleX);
										}
									
									sys_marker(NULL);
									sys_marker("b04");
									if (py<canvas_size.y-2)
										{
				//							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=pixel_for_bmap(canvas,px,py+1);
											pixel_to_vec(sample4,pixelalpha,format,pixel);
										}
									else
										{
											vec_set(sample4,sampleX);
										}
									
									sys_marker(NULL);
									sys_marker("b05");
									if ((px<canvas_size.x-2) && (py<canvas_size.y-2))
										{
				//							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=pixel_for_bmap(canvas,px+1,py+1);
											pixel_to_vec(sample5,pixelalpha,format,pixel);
										}
									else
										{
											vec_set(sample5,sampleX);
										}
									
									sys_marker(NULL);
									sys_marker("b06");
									if (px<canvas_size.x-2)
										{
				//							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=pixel_for_bmap(canvas,px+1,py);
											pixel_to_vec(sample6,pixelalpha,format,pixel);
										}
									else
										{
											vec_set(sample6,sampleX);
										}
									
									sys_marker(NULL);
									sys_marker("b07");
									if ((px<canvas_size.x-2) && (py>0))
										{
				//							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=pixel_for_bmap(canvas,px+1,py-1);
											pixel_to_vec(sample7,pixelalpha,format,pixel);
										}
									else
										{
											vec_set(sample7,sampleX);
										}
									
									sys_marker(NULL);
									sys_marker("b08");
									if (py>0)
										{
				//							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=pixel_for_bmap(canvas,px,py-1);
											pixel_to_vec(sample8,pixelalpha,format,pixel);
										}
									else
										{
											vec_set(sample8,sampleX);
										}
									
									sys_marker(NULL);
									sys_marker("b09");
									if ((px>0) && (py>0))
										{
				//							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=pixel_for_bmap(canvas,px-1,py-1);
											pixel_to_vec(sample9,pixelalpha,format,pixel);
										}
									else
										{
											vec_set(sample9,sampleX);
										}
										
									sys_marker(NULL);
									sys_marker("b10");
									// weighted average = ( own*7 , W*2 , NW , N*2 , NE , E*2 , SE , S*2 , SW ) / 19
									pixelcolor.red		= integer((sample1.x*strength + sample2.x*2 + sample3.x + sample4.x*2 + sample5.x + sample6.x*2 + sample7.x + sample8.x*2 + sample9.x)/(12+strength));
									pixelcolor.green	= integer((sample1.y*strength + sample2.y*2 + sample3.y + sample4.y*2 + sample5.y + sample6.y*2 + sample7.y + sample8.y*2 + sample9.y)/(12+strength));
									pixelcolor.blue	= integer((sample1.z*strength + sample2.z*2 + sample3.z + sample4.z*2 + sample5.z + sample6.z*2 + sample7.z  +sample8.z*2 + sample9.z)/(12+strength));
									
									sys_marker(NULL);
									sys_marker("b11");
									pixel=pixel_for_vec(pixelcolor,100,format);
		//							pixel_to_bmap(canvas,(canvas_size.x-1)-px,py,pixel);
									pixel_to_bmap(canvas,px,py,pixel);														
									sys_marker(NULL);
									
								}	// treshold check
						}			// for px
					
					bmap_unlock(canvas);
					
					Map_Progressbar(py/canvas_size.y*100);
					wait_for(Map_Progressbar);					
					
					draw_text( "PRESS 'B' TO BREAK BLURRING!" , 150 , 100 , vector(255,255,255) );
					if (key_b) break;
					
					wait(1); // without a wait after each line the loop could get too big if the shadow map is huge
					
				} 					// for py
		}							// for i
	
	reset(map_loadbar,SHOW); 
	reset( map_loadpanel , SHOW);
	wait(1);
}

© 2024 lite-C Forums