none
none

Reputation: 39

HLSL beginner needs some directions

Is there any example out there of a HLSL written .fx file that splats a tiled texture with different tiles?Like this: http://messy-mind.net/blog/wp-content/uploads/2007/10/transitions.jpg you can see theres a different tile type in each square and there's a little blurring between them to make a smoother transition,but right now I just need to find a way to draw the tiles on a texture.I have a 2D array of integers,each integer equals a corresponding tile type(0 = grass,1 = stone,2 = sand).I opened up a few HLSL examples and they were really confusing.Everything is running fine on the C++ side,but HLSL is proving to be difficult.

Upvotes: 0

Views: 966

Answers (2)

miloszmaki
miloszmaki

Reputation: 1645

You can use a technique called 'texture splatting'. It mixes several textures (color maps) using another texture which contains alpha values for each color map. The texture with alpha values is an equivalent of your 2D array. You can create a 3-channel RGB texture and use each channel for a different color map (in your case: R - grass, G - stone, B - sand). Every pixel of this texture tells us how to mix the color maps (for example R=0 means 'no grass', G=1 means 'full stone', B=0.5 means 'sand, half intensity').

Let's say you have four RGB textures: tex1 - grass, tex2 - stone, tex3 - sand, alpha - mixing texture. In your .fx file, you create a simple vertex shader which just calculates the position and passes the texture coordinate on. The whole thing is done in pixel shader, which should look like this:

float tiling_factor = 10; // number of texture's repetitions, you can also
                          // specify a seperate factor for each texture

float4 PS_TexSplatting(float2 tex_coord : TEXCOORD0)
{
    float3 color = float3(0, 0, 0);
    float3 mix = tex2D(alpha_sampler, tex_coord).rgb;
    color += tex2D(tex1_sampler, tex_coord * tiling_factor).rgb * mix.r;
    color += tex2D(tex2_sampler, tex_coord * tiling_factor).rgb * mix.g;
    color += tex2D(tex3_sampler, tex_coord * tiling_factor).rgb * mix.b;
    return float4(color, 1);
}

Upvotes: 2

djmj
djmj

Reputation: 5544

If your application supports multi-pass rendering you should use it.

You should use a multi-pass shader approach where you render the base object with the tiled stone texture in the first pass and on top render the decal passes with different shaders and different detail textures with seperate transparent alpha maps.
(Transparent map could also be stored in your detail texture, but keeping it seperate allows different tile-levels and more flexibility in reusing it.)

Additionally you can use different texture coordinate channels for each decal pass one so that you do not need to hardcode your tile level.

So for minimum you need two shaders, whereas Shader 2 is used as often as decals you need.

  1. Shader to render tiled base texture
  2. Shader to render one tiled detail texture using a seperate transparency map.

If you have multiple decals z-fighting can occur and you should offset your polygons a little. (Very similar to basic simple fur rendering.)

Else you need a single shader which takes multiple textures and lays them on top of the base tiled texture, this solution is less flexible, but you can use one texture for the mix between the textures (equals your 2D-array).

Upvotes: 1

Related Questions