Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question CreateAsset Texture2D with sprites and custom mipmaps

Discussion in '2D' started by KptMech, Feb 26, 2023.

  1. KptMech

    KptMech

    Joined:
    Dec 6, 2015
    Posts:
    10
    I have a utility which creates a spritesheet as a single Texture2D. It contains sprites and custom mipmaps (these were NOT autogenerated by Unity, I have populated them with Texture2D.SetPixels). I'm trying to store it in my assets folder so it doesn't rebuild it every time at startup during runtime.

    If I save it as a .png (using File.WriteAllBytes and ImageConversion.EncodeToPNG) I can then tweak TextureImporter.spritesheet to populate the list of sprites. However I lose my mipmaps, because png is not capable of storing that information. Other ImageConversion.Encode* functions don't seem to support mipmaps either.

    If I save it as a .asset (using AssetDatabase.CreateAsset) then I have mipmaps, but no sprites. I simply cannot get a TextureImporter for this file.

    Is there any way to export an image file which contains both mipmaps and a spritesheet?
     
    AlejMC likes this.
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,518
    Do you want to make your own mipmaps? That's usually not necessary.

    The mipmaps that Unity generates should be sufficient.

    Are you sure you set the import settings for the created texture correctly?

    Not sure of your workflow but it might be necessary to implement a custom texture importer to drive those importer settings to what you want before the actual import step. Otherwise, just set the import settings to include mipmaps.

    If you cannot enable mipmaps, it's usually due to not meeting the dimensional requirements, such as powers-of-2.
     
  3. KptMech

    KptMech

    Joined:
    Dec 6, 2015
    Posts:
    10
    My use case is to support variable zoom levels on a large map, the built-in autogenerated mipmaps are insufficient. I need the manually created mipmaps so I can emphasize important visual features of a zoomed out object, otherwise it just becomes blurry mess. I have also limited the mip count (don't need all 10)

    My workflow is as follows:
    1) Draw entities in gimp. Each mip and variation of the entity (I have modular sprites) is a layer
    2) Extract layers from gimp .xcf file into .bytes files using imagemagick (See why here)
    3) Load raw image data (.bytes) in a C# script at runtime, create a custom sprite atlas by manually populating pixels on a Texture2D and apply various graphical fixes such as extrusion/dilation, bleed padding and limiting the mip count. This is also where I invoke Sprite.Create for every single entity in my atlas
    4) I now have an optimised Texture2D and Sprite[] in my memory which the game can use

    I have found that Sprite.Create is quite slow when performed on a large number of sprites, so I am looking for ways to do step (3) only once from the editor, rather than every time at runtime. This would allow me to Resources.LoadAll<Sprite> which I hope would be significantly faster. The obstacle I am facing is that the Texture2D and Sprite[] I have in memory are not easily exportable together when custom mipmaps are involved. I found ways to export the texture with mipmaps (as a .asset), or export texture with spritesheet (as a .png), but not both a texture with mipmaps and a spritesheet. I want to create a file which contains both of those so that I can avoid invoking Sprite.Create at runtime. But unless there is a way to get a TextureImporter of a .asset (returns me a null, not sure if that's expected), or unless there is a way to inject mipmaps into an image file (Unity only exports .png, .jpg, .tga and .exr), or there is an alternative approach, then this will not be achievable.

    > custom texture importer

    Do you mean this? I will try to experiment with it, thank you. Perhaps I can call Sprite.Create somewhere there or modify the texture's mips. That is assuming such postprocessor is invoked at build time and not runtime
     
    AlejMC likes this.
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,518
    Sprites are just like any other asset: you can create them and then write them to disk. Sprites can just sit there as a file without even having the Texture2D they came from anywhere near, but it must be in the project obviously.

    The critical part is that the Texture2D they came from MUST already exist in the Unity AssetDatabase.

    This means just having the texture in memory is insufficient.

    This means just having written the texture to disk is insufficient.

    An asset import step of the textures in question MUST have taken place, or it somehow must have been placed into the AssetDatabase BEFORE you try to create the Sprite from it.

    Here's an example of writing a Mesh to disk. Same goes for Sprites:

    https://github.com/kurtdekker/makeg...9c/makegeo/Assets/Editor/MeshMakerAndSaver.cs
     
    KptMech likes this.
  5. KptMech

    KptMech

    Joined:
    Dec 6, 2015
    Posts:
    10
    Thank you Kurt, I was able to store my sprites. I saved the texture (as a .asset) and then each sprite individually (also as a .asset) in a dedicated folder. I have also checked and sprite1.texture == sprite2.texture which means batching is going to work as expected
     
  6. AlejMC

    AlejMC

    Joined:
    Oct 15, 2013
    Posts:
    149
    Would like to give a vote on this, if ever someone at the higher levels sees it: the ability to modify a bit the way mip maps are generated (either built-in options or somewhat easier API to inherit from for asset post processing).

    • I'm currently faking 'bloom' by just sampling the same texture at a lower mip bias for simple UI elements without having to go all the way into post processing.
      • "Gaussian Blur" of L0 put into L1-half res would look a lot better.
    • I remember old school 3D games even relying on mip maps for 'fog', the mip maps would slowly fade into a single color :O (I agree, that's hardcore).
    Unreal actually has support for many MipMap generation modes (Gaussian, normal, some others I can't remember) learned not long ago (I don't use Unreal, maybe it's been there since forever).

    Anyways, I think that's useful. It's somewhere in there, ReflectionProbes use already a very specific mip map generation, for example, as they have to simulate specular reflections at the different [0 to 1] roughness levels.