Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by Panzerhandschuh · Oct 15, 2013 at 02:48 AM · textureruntimeloadingdds

Can you load dds textures during runtime?

My game lets users create custom content so loading a large number of textures quickly is important. I was wondering if it was possible to load dds files since they already have dxt info stored in them and it would be much faster than loading a jpg or png.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
12

Answer by jeff-smith · May 14, 2014 at 03:13 PM

I've found a lot of good help on the Unity forums, so it is my turn to provide an answer.

DDS (DirectDraw Surface) files can be loaded in Unity at runtime using the Texture2D LoadRawTextureData() method. On our project at NOAA, we are loading hundreds of 4000 x 2000 jpg images and the time required to load each texture and compress it was roughly 600 ms (milliseconds). Too slow!

I found that the time required to load the DDS version of the same image (with DXT1 compression) is roughly 3 ms! Amazingly fast. So how can you get your images into DDS format, and how can you load them in Unity?

To save your images into DDS format, you can use Photoshop with the Nvidia texture tools plugin (https://developer.nvidia.com/nvidia-texture-tools-adobe-photoshop), or you can use a free tool like GIMP (with its DDS plugin--https://code.google.com/p/gimp-dds/). I used GIMP 2.8 with the plugin. Load your jpg/png image(s) into one of these tools, and then export it as a DDS file. Choose DXT1 compression if your image doesn't have an alpha channel (e.g., JPG images) or DXT5 compression if your images do have alpha (e.g., PNG).

To load your DDS file in Unity, you'll need to read the DDS header which is described in detail here: http://doc.51windows.net/Directx9_SDK/?url=/directx9_sdk/graphics/reference/DDSFileReference/ddsfileformat.htm

Basically, a DDS file has a 128 byte header which contains some useful information like the width and height of your image. You need to exclude the header bytes, however, when you pass the bytes to the LoadRawTextureData method (which was added in Unity 4.3 but sadly has not yet been documented). Here's my code for loading a DDS file into a Texture2D within a class named TextureLoader:

 public static Texture2D LoadTextureDXT(byte[] ddsBytes, TextureFormat textureFormat)
 {
     if (textureFormat != TextureFormat.DXT1 && textureFormat != TextureFormat.DXT5)
         throw new Exception("Invalid TextureFormat. Only DXT1 and DXT5 formats are supported by this method.");
 
     byte ddsSizeCheck = ddsBytes[4];
     if (ddsSizeCheck != 124)
         throw new Exception("Invalid DDS DXTn texture. Unable to read");  //this header byte should be 124 for DDS image files
 
     int height = ddsBytes[13] * 256 + ddsBytes[12];
     int width = ddsBytes[17] * 256 + ddsBytes[16];
 
     int DDS_HEADER_SIZE = 128;
     byte[] dxtBytes = new byte[ddsBytes.Length - DDS_HEADER_SIZE];
     Buffer.BlockCopy(ddsBytes, DDS_HEADER_SIZE, dxtBytes, 0, ddsBytes.Length - DDS_HEADER_SIZE);
 
     Texture2D texture = new Texture2D(width, height, textureFormat, false);
     texture.LoadRawTextureData(dxtBytes);
     texture.Apply();
 
     return (texture);
 }
 

So you just need to read the bytes from a DDS file and then pass them to this C# method. Here's some simple code to do that:

byte[] bytes = System.IO.File.ReadAllBytes(ddsFilePath);

Texture2D myTexture = TextureLoader.LoadTextureDXT(bytes, TextureFormat.DXT1);

You should see 100x speedup in loading images into Texture2Ds. I hope this post helps someone.

Comment
Add comment · Show 8 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Julien-Lynge · May 14, 2014 at 03:54 PM 0
Share

Very thorough answer :)

avatar image tylo · Jun 11, 2014 at 01:20 AM 0
Share

I have been attempting to use your method, but keep getting this error. Did you run into this at all?

 UnityException: LoadRawTextureData: not enough data provided (will result in overread).
 Utility.LoadTexture (System.Byte[] ddsBytes) (at Assets/Scripts/Utilities/Utility.cs:134)

The file is definitely a DDS file. It loads the header and accurately obtains the width and height.

avatar image tylo · Jun 11, 2014 at 09:39 PM 1
Share

I found out my above error was caused by trying to LoadRawTextureData into a Texture that I had mipmaps set to true. $$anonymous$$y DDS file had no mipmaps, so it was unable to deal with that.

Setting mipmaps to false when initializing my texture fixed the problem.

avatar image Julien-Lynge · Jun 12, 2014 at 07:02 AM 0
Share

That's a subtle error - glad you figured it out!

The docs for LoadRawTextureData are nonexistent, so a lot of what we've figured out is by trial and error. I've been wary to try anything fancy, like loading into a cubemap or a texture with mipmaps. Good to know that it appears to support mipmaps.

It would be really nice for debugging to have the reverse method, e.g. ReadRawTextureData, which would return a byte stream so we know what Unity is expecting..

avatar image jeff-smith · Jun 12, 2014 at 06:07 PM 1
Share

Glad you figured that out, Tylo. You'll also see that error message if your texture.format is mismatched. For example if texture.format=TextureFormat.ARGB32 (PNG) and yet your source DDS file is 24 bit (JPG with no alpha).

Show more comments
avatar image
0

Answer by tylo · May 22, 2018 at 02:11 AM

In case anyone else stumbles on this, you can also detect what compression algorithm the DDS file is using by checking bytes in the header file.

 ddsBytes[84], ddsBytes[85], ddsBytes[86], ddsBytes[87]

Each one of these bytes contains the ASCII values of a 4 letter code.

DXT1 and DXT5 are the most relevant in the case of Unity.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by phoenixrising · Oct 23, 2018 at 05:51 PM

You can also use Unity's crunch to process on the command line

https://github.com/Unity-Technologies/crunch

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

20 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Apply transparent texture to plain at runtime 1 Answer

Runtime Normal Map Import Issues 0 Answers

Assigning UV Map to model at runtime 0 Answers

Loading texture file from png/jpg file on disk 5 Answers

Reverse of Texture.EncodeToEXR in unity? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges