您如何将不同尺寸的图像与一个图像的大小相结合,而尺寸为2?
某些上下文
我正在从事体素游戏(例如Minecraft)的 。我无法使用预建的纹理地图集,因为我需要允许玩家在游戏中添加自定义块。这就是为什么我必须根据所提供的纹理在运行时创建纹理地图集的原因。这些纹理的尺寸不一定(一个可以是16 x 16,而另一个可以是64 x 64),所以我不能只在常规距离上粘贴图像。
实际问题
我如何结合多个图像,这些图像可以将不同的大小分解为一个,而我可以尽可能多地填充图像,以及图像应尽可能密集地包装,并且如果可以将图像放在最终图像上的较小位置应该放置在那里,以免使用其他图像可能使用的空间。 最终图像必须是一个正方形,其大小必须是2的最小功率。例如,如果有4 x 16张图像,则只能创建一个32 x 32映像,足以包含这些图像。但是说有5张图像,它应该创建一个64 x 64张图像,因为它的最小尺寸可以包含这些图像。 我还需要可以将其映射到区块的纹理的UV值。
游戏引擎我使用的
是我使用Godot游戏引擎。
Some context
I am working on a voxel game (like minecraft). I can not use a prebuilt texture atlas as I need to allow players to add custom blocks to the game. That's why I must create texture atlases at the runtime based on the textures provided. These textures need not be same in size (one can be 16 by 16 while other can be 64 by 64) so I can't just paste the images at a regular distance.
Actual question
How can I combine multiple images which can be different sizes into one while cramming as much images I can, i.e., images should be as densely packed as possible and if an image can be placed at a smaller place on the final image, it should be placed there as to not use the space that may be used by other images.
The final image must be a square and its size must be the smallest power of 2. For example if there are 4 16 by 16 images, only a 32 by 32 image should be created as its enough to contain those images. But say that there were 5 images, it should create a 64 by 64 image as its the smallest size that can contain those images.
I would also need the UV values of the textures that I can map to blockfaces.
Game engine I use
I use godot game engine.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
输入
让我们说您有一系列
image
要放入纹理地图集。我们说这是一个数组:该数组的值可以是:
image
。get_data
on纹理>纹理
s获取。图像
在运行时通过其他方式创建的。现在编译尺寸
,我们可以得到它们的尺寸。我们将在
poolvector2array
中需要它们(我们实际上可以在常规array
中获取它们并进行转换,但是没有必要执行此操作):计算Atlas
一旦有尺寸,我们就可以调用
geome.make_atlas
:geemoge.make_atlas
的算法将尝试制作Atlas Square。我们应该查询我们得到的大小:
可悲的是,戈多不会暴露“ 2”功能的“下一个力量”。在上下文的情况下,我相信一个简单的循环在这种情况下会做得很好:
构建Atlas
创建一个Atlas
image
现在我们已经确定了大小,我们可以创建一个新的
图像
用于地图集:您可能会怀疑前两个参数是
width
和height
。第三个参数是您是否要生成MIPMAP。最后一个是像素格式,我在这里选择的格式有四个通道(红色,绿色,蓝色,alpha),分别为8位(颜色深度)。将输入
图像
s复制到地图集图像
现在将原始图像复制到地图集。我们在从
make_atlas
中获得的结果获得每个位置:这是
rect2
是image> image
我们要绘制的区域(所有)。注意根据要绘制的
image
的格式,您可能必须先转换它:而且,通常,图像以压缩格式导入,无法为直接转换,因此您必须首先解压缩:
如果
BLIT_RECT
行给您问题,请尝试一下。UV坐标
顺便说一句,您说要紫外线坐标,我们应该从相同的循环中获取它们:
转换为
纹理
,并且由于您想要紫外线坐标,我认为这是对于某些着色器,将成为
纹理
。因此,让我们做一个纹理
:然后您应该能够将其设置在需要的地方。我把它留给你。
Inputs
Let us say you have a series of
Image
s you want to put into your texture atlas. Let us say it is an array:And the values of that array can be either:
Image
.get_data
onTexture
s.Image
s created at runtime by other means.Compiling the sizes
Now, we can get their sizes. We are going to need them in a
PoolVector2Array
(we can actually get them in a regularArray
and convert it, but there is no need to do that):Computing the atlas
Once we have the sizes, we can call
Geometry.make_atlas
:The algorithm of
Geometry.make_atlas
will try to make the atlas square.We should query what size we got:
Sadly Godot does not expose a "next power of 2" function. Given the context, I believe a simple loop will do well on this case:
Building the atlas
Create an atlas
Image
Now that we have decided the size, we can create a new
Image
for the atlas:As you might suspect the first two parameters are
width
andheight
. The third parameter is whether or not you want to generate mipmaps. And the last is the pixel format, the one I'm picking here has four channels (Red, Green, Blue, Alpha) of 8 bits (color depth) each.Copy the input
Image
s to the atlasImage
Now copy your original images to the atlas. We get the position for each one on the result we got from
make_atlas
:Here the
Rect2
is the area of theImage
we want to draw (all of it).Note depending on the format of the
Image
you want to draw, you may have to convert it first:Also, usually, the images are imported in a compressed format that cannot be converted directly, and thus you would have to decompress first:
If the
blit_rect
line is giving you problems, try that.UV Coordinates
By the way, you say you want UV coordinates, we should get them from the same loop:
Converting to
Texture
And since you want UV coordinates, I presume this is going to be a
Texture
for some shader. So, let us make aTexture
:Then you should be able to set it where you need it. I leave that to you.