一些背景關系
我正在開發體素游戲(如我的世界)。我不能使用預構建的紋理圖集,因為我需要允許玩家在游戲中添加自定義塊。這就是為什么我必須在運行時根據提供的紋理創建紋理圖集。這些紋理的大小不必相同(一個可以是 16 x 16,而另一個可以是 64 x 64),所以我不能只是將影像粘貼在固定距離。
實際問題
如何將多個不同尺寸的影像組合成一個,同時盡可能多地塞滿影像,即影像應該盡可能密集,如果影像可以放置在最終影像的較小位置,它應該是放在那里是為了不使用其他影像可能使用的空間。最終影像必須是正方形,并且它的大小必須是 2 的最小冪。例如,如果有 4 個 16 x 16 影像,則應該只創建一個 32 x 32 影像,因為它足以包含這些影像。但是假設有 5 個影像,它應該創建一個 64 x 64 的影像作為可以包含這些影像的最小尺寸。我還需要可以映射到塊面的紋理的 UV 值。
我使用的游戲引擎
我使用godot游戲引擎。
uj5u.com熱心網友回復:
輸入
假設您有一系列Image
s 想要放入紋理圖集中。假設它是一個陣列:
var images:Array
該陣列的值可以是:
- 匯入為
Image
. - 從呼叫s 中
get_data
得到。Texture
Image
s 在運行時通過其他方式創建。
編譯尺寸
現在,我們可以得到它們的尺寸。我們將需要它們PoolVector2Array
(我們實際上可以將它們放在常規中Array
并轉換它,但沒有必要這樣做):
var sizes:PoolVector2Array
for image in images:
sizes.append(image.get_size())
計算圖譜
一旦我們有了尺寸,我們就可以呼叫Geometry.make_atlas
:
var atlas_data := Geometry.make_atlas(sizes)
的演算法Geometry.make_atlas
將嘗試使圖集正方形。
我們應該查詢我們得到的大小:
var min_atlas_size:Vector2 = atlas_data.size
可悲的是,Godot 沒有公開“2 的下一個冪”函式。鑒于背景關系,我相信一個簡單的回圈在這種情況下會做得很好:
var atlas_size := 16
while min_atlas_size.x > atlas_size or min_atlas_size.y > atlas_size:
atlas_size *= 2
構建圖集
創建地圖集Image
現在我們已經確定了大小,我們可以Image
為圖集創建一個新的:
var atlas := Image.new()
atlas.create(atlas_size, atlas_size, true, Image.FORMAT_RGBA8)
您可能會懷疑前兩個引數是width
和height
。第三個引數是是否要生成mipmap。最后一種是像素格式,我在這里選擇的有四個通道(紅色、綠色、藍色、Alpha),每個通道 8 位(顏色深度)。
將輸入Image
的 s 復制到圖集Image
現在將您的原始影像復制到圖集。我們從以下結果中獲得每個人的位置make_atlas
:
var points:PoolVector2Array = atlas_data.points
for index in images.size():
var image:Image = images[index]
var point:Vector2 = points[index]
var size:Vector2 = image.get_size()
atlas.blit_rect(image, Rect2(Vector2.ZERO, size), point)
這Rect2
是Image
我們要繪制的區域(全部)。
請注意,根據Image
您要繪制的格式,您可能需要先轉換它:
source.convert(Image.FORMAT_RGBA8)
此外,通常,影像是以無法直接轉換的壓縮格式匯入的,因此您必須先解壓縮:
source.decompress()
source.convert(Image.FORMAT_RGBA8)
如果blit_rect
線路給您帶來問題,請嘗試。
紫外線坐標
順便說一句,你說你想要 UV 坐標,我們應該從同一個回圈中獲取它們:
var points:PoolVector2Array = atlas_data.points
var uv_scale := 1.0/atlas_size
var uv_rects := []
for index in images.size():
var image:Image = images[index]
var point:Vector2 = points[index]
var size:Vector2 = image.get_size()
atlas.blit_rect(image, Rect2(Vector2.ZERO, size), point)
uv_rects.append(Rect2(point * uv_scale, size * uv_scale))
轉換為Texture
既然你想要 UV 坐標,我想這將是一個Texture
著色器。所以,讓我們做一個Texture
:
var texture_atlas := ImageTexture.new()
texture_atlas.create_from_image(atlas)
然后你應該能夠將它設定在你需要的地方。我把它留給你。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/469376.html
上一篇:異步KafkaProducer批量大小為linger.ms
下一篇:如何使影像不與div的邊框重疊