1
votes

This is my first time here (With an account), I'm looking to make a height-map editor with XNA 4.0 (Somewhat similar to Earth2150's, if you've played it).

I've written a custom Effect File here: http://pastebin.com/CUFtB8Z9

It blends textures just fine, except it blends over the entire map.

What I really want is to be able to have multiple textures on my heightmap (Which i'll then blend with the nearest other texture) and I am looking for ways to do this.

I thought about assigning a float in my Vertex Declaration, then using an array of textures to "Assign" a texture to a specific vertex. But how would I go about getting my effect file to take in a different value for a texture on each vertex?

Sorry about not being very clear, here is my Draw code and my Vertex Declaration:

(Excuse the random number changing, It was my attempt to try and get each vertex to pick a random texture)

public void Draw(Texture2D[] TextureArray)
{
    RasterizerState rs = new RasterizerState();
    rs.CullMode = CullMode.None;
    //rs.FillMode = FillMode.WireFrame;
    EditGame.Instance.GraphicsDevice.RasterizerState = rs;
    Random rnd = new Random();

    foreach (EffectPass pass in EditGame.Instance.baseEffect.CurrentTechnique.Passes)
    {
        if (SlowCounter == 60)
        {
            EditGame.Instance.baseEffect.Parameters["xTexture"].SetValue(TextureArray[rnd.Next(0, 2)]);
            EditGame.Instance.baseEffect.Parameters["bTexture"].SetValue(TextureArray[rnd.Next(0, 2)]);
            SlowCounter = 0;
        }

        pass.Apply();
        EditGame.Instance.GraphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, 0, indices.Length / 3, VP2TC.VertexDeclaration);
    }
    SlowCounter++;
}

public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration(
    new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
    new VertexElement(12, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate,0),
    new VertexElement(20, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate,1),
    new VertexElement(28, VertexElementFormat.Single, VertexElementUsage.BlendWeight,0),
    new VertexElement(32, VertexElementFormat.Vector3,VertexElementUsage.Normal,0),
    new VertexElement(44, VertexElementFormat.Color,VertexElementUsage.Color,0)
);
1
I'm not entirely clear on what you're looking for. Are you trying to get a different blend of textures on a per vertex basis?Martin

1 Answers

1
votes

As I said in my comment, I'm not certain this is what you're looking for but I'll go ahead anyway.

I think what you probably want is described here.

Essentially you have a Vector 4 which stores the weights of each texture and then take a weighted average of all 4 textures weighted by the individual elements in the vector (acting as 4 blend weights).

If you want to blend textures without having to have a blend element for every single texture things get more fun.

You could have a single blend weight, which essentially picks the blending of 2 adjacent textures in order. So if you have:

  1. Snow
  2. Grass
  3. Rock
  4. Sand

Blend Weight = 0.5

Would pick a blend of Grass (0.25) and Rock (0.75). Blended in equal amounts (since it's halfway between them).

If you want lots of textures, your shader is going to become very cumbersome with ~50 texture samplers. If you really want this many textures you should consider a texture atlas or just procedurally generated virtual textures with the blending already done at generation time.