1
\$\begingroup\$

I am new to shaders and HLSL so bare with me on this one.

I have a 2D tile map in my game and want to create a mini-map, at first I was just copying all the data from one sprite batch to another and rendering it in a smaller camera. This obviously has a performance issue.

So I want to make a mini-map that is composed of coloured pixels depending on what is in that particular cell.

I have a basic shader going at the moment that converts tex coordinates to pixel position but now I need a way to determine what color to set it. My instant decision was to simply pass in a 2d array of colors and grab the color using the x and y coordinate of the pixel, this crashed lol.

Here is what I have so far for the shader:

sampler s0;

// The width and height of the texture being sampled
int width, height;

float4 PixelShaderFunction(float2 coords : TEXCOORD0) : COLOR0
{
    float4 color = tex2D(s0, coords);
    // Covert the tex coordinates to pixel coordinates
    int2 tc = int2(width * coords.x, height * coords.y);

    // Here I need to do some sort of check or something?

    return color;
}

technique Technique1
{
    pass Pass1
    {
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}

How can I pass the color data to the pixel shader so it knows what color to set each pixel? I already know how to pass data but not sure how I can represent that data to pass it.

My map is every changing and units are moving around constantly, so the data will be passed in almost every frame.

\$\endgroup\$
3
  • \$\begingroup\$ "This obviously has a performance issue." Have you proven this? \$\endgroup\$
    – William
    Feb 26, 2015 at 11:29
  • \$\begingroup\$ Well given the fact my frame rate gets sliced in half when I render the mini-map, I guess so? lol. This might be due to my method, as all I am doing is rendering the map again but at a smaller scale. The actual map rendering is not optimized, but the mini-map with the current system will ALWAYS render everything (unlike the world camera which has culling). \$\endgroup\$
    – Gibbo
    Feb 26, 2015 at 11:32
  • \$\begingroup\$ That's good to know. Just making sure you're not optimizing prematurely. ;) \$\endgroup\$
    – William
    Feb 26, 2015 at 11:38

2 Answers 2

1
\$\begingroup\$

I think it's bad idea pass tile map to shader. Match better will be just create bitmap and initialize colors pixel-by-pixel. Create bitmap with same size as your tilemap has and then draw part of them.

Create minimap bitmap:

 Bitmap miniMapBitmap = new Bitmap(worldWidth, worldHeight);
    for (int x = 0; x < worldWidth; x++)
    {
        for (int y = 0; y < worldHeight; y++)
        {
            miniMapBitmap.SetPixel(x, y, GetMiniMapColor(x, y)); // place for conditions :D
        }
    }

Create Texture2D from bitmap:

Texture2D miniMapTexture = null;
using (MemoryStream stream = new MemoryStream() )
{
    bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
    stream.Seek(0, SeekOrigin.Begin);
    miniMapTexture = Texture2D.FromFile(GraphicsDevice, stream);
}

Draw part of minimap texture corresponding to visible tiles (for example):

spritebatch.Draw(
    miniMapTexture,
    miniMapPosition,
    new Rectangle(cameraOffsetX, cameraOffsetY, screenWidth, screenHeight),
    Color.White);
\$\endgroup\$
0
\$\begingroup\$

In my game, I do this by setting UVS in vertex data and drawing a mesh for the map using texture coords from the vertex data. Basically:

  • Create a tile map that is the same aspect ratio as the sprite sheet you are using to draw your current tile map; where each pixel represents a tile.
  • Pass this to the shader.
  • Create a vertex buffer that is just a mesh representing your tile map. You can do this either by creating a mesh grid filled with triangles, or by drawing the map as a point set.
  • Each vertex's UV coordinates are defined by its tile type.
  • The fragment shader looks up into the tile map color sheet to determine what color to draw.
  • Render the entire thing to a render target with an orthographic camera. The contents of the render target are now your mini-map.

Technically, you only need to render this once each time the map changes, but I render it every frame in my game so I can do things like have a 3D effect, or have animated bits of the mini-map.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .