Topic was automatically imported from the old Question2Answer platform.
Asked By
keenfoong
Hi is it possible to get the mipmap data from a texture? I’m trying to get a low resolution version of a texture. I was thinking of copying the texture and resizing it, but if there’s a way to access the mipmap that might be better.
There are only a few corner cases where it makes sense to directly access the mipmaps.
Normally you’d want to let godot handle it automatically for you.
But for the interested and since i just had the same need:
func _get_bytes_per_pixel(format):
# This will only work for uncompressed formats
# where each pixel has the same ammount of bytes.
var tmp = Image.new()
tmp.create(1, 1, false, format)
return tmp.get_data().size()
func get_mipmap(img, level, bytes_per_pix=null):
# Supports all MIP levels,
# but has some limitations regarding formats.
assert img.has_mipmaps()
if img.is_compressed():
img.decompress()
if bytes_per_pix == null:
bytes_per_pix = _get_bytes_per_pixel(img.get_format())
var mip_offset = img.get_mipmap_offset(level)
var size = img.get_size()
var new_width = int(size.x / pow(2, level))
var new_height = int(size.y / pow(2, level))
var buffer = img.get_data().subarray(mip_offset, mip_offset + bytes_per_pix * new_width * new_height - 1)
var mip = Image.new()
mip.create_from_data(new_width, new_height, false, img.get_format(), buffer)
assert mip.get_size() == Vector2(new_width, new_height)
return mip
func _get_mipmap(img, level):
# Doesn't need to care about formats,
# but can't handle the smallest MIP level.
assert img.has_mipmaps()
if img.is_compressed():
img.decompress()
var mip_offset = img.get_mipmap_offset(level)
var next_offset = img.get_mipmap_offset(level + 1)
assert mip_offset >= 0 and next_offset > 0
var size = img.get_size()
var new_width = int(size.x / pow(2, level))
var new_height = int(size.y / pow(2, level))
var buffer = img.get_data().subarray(mip_offset, next_offset - 1)
var mip = Image.new()
mip.create_from_data(new_width, new_height, false, img.get_format(), buffer)
assert mip.get_size() == Vector2(new_width, new_height)
return mip
One can also access the mipmaps from fragment shaders via the textureLod function.