0 registered members (),
1,094
guests, and 1
spider. |
Key:
Admin,
Global Mod,
Mod
|
|
|
Re: Slope Blendmap Generator
[Re: Superku]
#434116
12/13/13 08:04
12/13/13 08:04
|
Joined: Mar 2011
Posts: 3,150 Budapest
sivan
Expert
|
Expert
Joined: Mar 2011
Posts: 3,150
Budapest
|
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):
#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();
}
}
|
|
|
Re: Slope Blendmap Generator
[Re: Random]
#434117
12/13/13 09:10
12/13/13 09:10
|
Joined: Aug 2002
Posts: 3,258 Mainz
oliver2s
OP
Expert
|
OP
Expert
Joined: Aug 2002
Posts: 3,258
Mainz
|
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) 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 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.
|
|
|
Re: Slope Blendmap Generator
[Re: oliver2s]
#434118
12/13/13 09:17
12/13/13 09:17
|
Joined: May 2009
Posts: 5,370 Caucasus
3run
Senior Expert
|
Senior Expert
Joined: May 2009
Posts: 5,370
Caucasus
|
Thank you man, it's really awesome to see some great contributions, bringing our forum alive! 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 Greets
|
|
|
Re: Slope Blendmap Generator
[Re: 3run]
#434120
12/13/13 10:43
12/13/13 10:43
|
Joined: Mar 2011
Posts: 3,150 Budapest
sivan
Expert
|
Expert
Joined: Mar 2011
Posts: 3,150
Budapest
|
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):
// 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);
}
|
|
|
|