【问题标题】:Tileset generator瓦片集生成器
【发布时间】:2012-12-26 19:59:16
【问题描述】:

我一直在尝试创建一个瓦片集生成器(将两个图像混合在一起),但我不知道需要哪种方法才能使一个纹理/图像重叠到主纹理/图像上,或者以某种方式淡出在特定点 - 或者这是不能自动完成(或不应该完成)的事情?

随着绿色图像的淡出,蓝色图像应在绿色图像之上淡入以进行平滑过渡。如果我已经有两张图片 - 我该怎么做?

现在,我只能剪掉蓝色的部分。所以剩下的唯一部分是绿色,当我尝试添加叠加层时,它只是很难看,我认为 alpha 级别应该会增加(越靠近右下角,蓝色应该越蓝)。

有什么我应该看的想法吗?

我目前的方法:但目前,这只适用于一个角,但应该适用于“所有”角;不知道是什么原因造成的。

Point in polygon method

public static Bitmap GenerateTile(Bitmap bitmap, Bitmap copyFrom, int x, int y, int width, int height, Point[] cutoff)
{
        if (bitmap.Size != copyFrom.Size)
            throw new Exception("Invalid image size. Image sizes must match");

        Bitmap bmap = new Bitmap(width, height);
        Bitmap overlay = new Bitmap(width, height);

        Point min, max;
        float alpha;

        // returns minimum x, y and maximum x, y
        GetCorners(cutoff, out min, out max);

        for (int bx = x; bx < (x + width); bx++)
        {
            for (int by = y; by < (y + height); by++)
            {
                if (!IsInPolygon2(cutoff, new Point(bx, by)))
                {
                    bmap.SetPixel(bx, by, bitmap.GetPixel(bx, by));
                }
                else
                {

                    alpha = ((float)((max.X - bx) + (max.Y - by)) / (float)((max.X - min.X) + (max.Y - min.Y)));

                    if (alpha >= 0 && alpha <= 0.5f)
                    {
                        bmap.SetPixel(bx, by, Color.FromArgb((int)((alpha / 0.5f) * 255f), bitmap.GetPixel(bx, by)));
                        overlay.SetPixel(bx, by, Color.FromArgb((int)(255f - ((alpha / 0.5f) * 255f)), copyFrom.GetPixel(bx, by)));
                    }
                }
            }
        }

        using (Graphics g = Graphics.FromImage(bmap))
        {
            g.DrawImageUnscaled(overlay, 0, 0);
        }

        return bmap;
}

我的方法返回以下结果(还不好):

// bottom right corner
points.Add(new Point(image.Width / 2, image.Height));
points.Add(new Point(image.Width, image.Height / 2));
points.Add(new Point(image.Width, image.Height));
points.Add(new Point(image.Width / 2, image.Height));

// rightside
points.Add(new Point(image.Width / 2, image.Height));
points.Add(new Point(image.Width, image.Height));
points.Add(new Point(image.Width, 0));
points.Add(new Point(image.Width / 2, 0));
points.Add(new Point(image.Width / 2, image.Height));

【问题讨论】:

  • 希望这应该适用于更高级的图像,如真实纹理。
  • 您能否发布一张您希望看到的图片以及实际发生的情况以及执行此操作的代码?
  • 主图在整体图上,叠加层向右下角慢慢淡入。或者类似的东西在两个图块之间进行过渡。
  • 您正在使用SetPixel 执行此操作,但如果您有很多电话,这将非常慢。我认为这应该通过 alpha 掩码来完成,尽管我不确定。
  • 如何在不使用着色器的情况下预先对图像进行 alpha 遮罩?仅用于 Tileset 生成器。

标签: c# image-processing xna drawing tiles


【解决方案1】:

我会尝试将草和雪纹理混合在一起作为 3D 基元。这样,您就不需要为纹理和淡入淡出方向的每种组合生成单独的位图。为了演示,这里有一段代码 sn-p 可以粘贴到 Visual Studio 中默认 XNA 项目的 Draw 方法中:

GraphicsDevice.Clear(Color.CornflowerBlue);
GraphicsDevice.BlendState = BlendState.NonPremultiplied;
effect.TextureEnabled = true;
effect.VertexColorEnabled = true;
effect.World = Matrix.CreateTranslation(new Vector3(-0.5f, -0.5f, 0))
    * Matrix.CreateScale(300)
    * Matrix.CreateTranslation(-Vector3.UnitZ);
effect.Projection = Matrix.CreateOrthographic(GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 1, 10000);
effect.View = Matrix.CreateLookAt(Vector3.UnitZ, Vector3.Zero, Vector3.UnitY);

var grassVertices = new[]
{
    new VertexPositionColorTexture(Vector3.Zero, new Color(1f, 1f, 1f, 1f), Vector2.Zero),
    new VertexPositionColorTexture(Vector3.UnitY, new Color(1f, 1f, 1f, 1f), Vector2.UnitY),
    new VertexPositionColorTexture(new Vector3(1, 1, 0), new Color(1f, 1f, 1f, 1f), Vector2.One),
    new VertexPositionColorTexture(Vector3.Zero, new Color(1f, 1f, 1f, 1f), Vector2.Zero),
    new VertexPositionColorTexture(new Vector3(1, 1, 0), new Color(1f, 1f, 1f, 1f), Vector2.One),
    new VertexPositionColorTexture(Vector3.UnitX, new Color(1f, 1f, 1f, 0f), Vector2.UnitX),
};
effect.Texture = grassTexture;
effect.Techniques[0].Passes[0].Apply();
GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, grassVertices, 0, 2);

var snowVertices = new[]
{
    new VertexPositionColorTexture(Vector3.Zero, new Color(1f, 1f, 1f, 0f), Vector2.Zero),
    new VertexPositionColorTexture(Vector3.UnitY, new Color(1f, 1f, 1f, 0f), Vector2.UnitY),
    new VertexPositionColorTexture(new Vector3(1, 1, 0), new Color(1f, 1f, 1f, 0f), Vector2.One),
    new VertexPositionColorTexture(Vector3.Zero, new Color(1f, 1f, 1f, 0f), Vector2.Zero),
    new VertexPositionColorTexture(new Vector3(1, 1, 0), new Color(1f, 1f, 1f, 0f), Vector2.One),
    new VertexPositionColorTexture(Vector3.UnitX, new Color(1f, 1f, 1f, 1f), Vector2.UnitX),
};
effect.Texture = snowTexture;
effect.Techniques[0].Passes[0].Apply();
GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, snowVertices, 0, 2);

下面是 LoadContent 方法中初始化资源所需的内容:

grassTexture = Content.Load<Texture2D>("grass");
snowTexture = Content.Load<Texture2D>("snow");
effect = new BasicEffect(GraphicsDevice);

要在其他方向创建平铺淡入淡出,您只需编辑grassVerticessnowVertices。对于直接向右、向左、向上或向下的淡入淡出,您需要使用四个三角形而不是两个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-11
    相关资源
    最近更新 更多