 const int ACTION_SOLIDIFY = 2;
 const int ACTION_LEVEL = 3;
 
+const float DIRT_THRESHOLD = 0.2;
+
 void main() {
 
 	float height = texture(tex_in_height, uv)[0];
 	if (height < dirt_max_height) {
 		if (action == ACTION_CREATE) {
 			float height = texture(tex_in_height, uv)[0];
-			float dirt = min(dirt_amount, dirt_max_height - height);
+			float diff = dirt_max_height - height;
+			float dirt = min(dirt_amount, diff * diff* dirt_max_slope);
 			tex_out_height = vec4(height, 0, 0, 1);
 			tex_out_dirt = vec4(dirt, 0, 0, 1);
 		}

		else if (action == ACTION_LEVEL) {
			float height = texture(tex_in_height, uv)[0];
			vec4 dirt = texture(tex_in_dirt, uv);
			
			float sum = height;
			for(int i = -1; i <= 1; i++) {
				for(int j = -1; j <= 1; j++) {
					if (i != 0 || j != 0) { 
						vec2 uv_ij = uv + vec2(i, j) * vec2(DX, DY);
						float height_ij = texture(tex_in_height, uv_ij)[0];

						sum += height_ij;
					}
				}
			}

			height = sum / 9.0;
			tex_out_height = vec4(height, 0, 0, 1);
			tex_out_dirt = dirt;
		}


			float next_dirt;
			if (min_i != 0 && min_j != 0){
				if ((level - min_level) > DZ * dirt_max_slope) {
					float diff = (level - min_level) - DZ * dirt_max_slope;
					float extra = min(diff/2.0, dirt);
			
					dirt = dirt - extra;
					next_dirt = extra;
				}
			} else if (min_i != 0 || min_j != 0){
				if ((level - min_level) > DX * dirt_max_slope) {
					float diff = (level - min_level) - DX * dirt_max_slope;
					float extra = min(diff/2.0, dirt);
					dirt -= extra;
					next_dirt = extra;
