16bit image support?

I know I can import a heightmap, but I want to do this via code. My code is fine, I can read in 8bit png’s and such, but on importing a 16bit png (or tif), I get:

Texture import error [Assets/Resources/Terrain/Terrain_01_00.png]: Texture import error: Assets/Resources/Terrain/Terrain_01_00.png

…and thus the Resource.Load doesn’t find a texture at all!

With an 8bit heightmap, I get the horrible results of using an 8bit heightmap. To wit:

I would guess Unity doesn’t support 16-bit for png or tiff. You can read 16-bit raw files, which you’ll have to parse yourself, but that’s not hard.

–Eric

Well, i’m part-way there. The result looks like it’s derived from the heightmap but isn’t quite it! I wonder if the Unity guys might be able to shed some light on it as they already have the Import RAW function!

ImportHeightmapAuto.cs

using UnityEngine;
using UnityEditor;
using System.Collections;

public class ImportHeightMapAuto : ScriptableObject
{
    [MenuItem("Custom/Terrain/Import Heightmap (auto)")]

    static void ImportHeightmapAuto()
    {
        float[,] temp = TerrainHelper.HeightToArray("Terrain_128_128", 257);
        Terrain.activeTerrain.terrainData.SetHeights(0, 0, temp);
    }

TerrainHelper.cs

using UnityEngine;
using System;
using System.IO;

public class TerrainHelper
{
    public static int TResH;
    public static int TResW;

    public static float[,] HeightToArray(string TName, int TRes)
    {
        string FileName = TName + ".r16";
        FileStream FS = new FileStream("Assets/Frontier_Height.raw", FileMode.Open, FileAccess.Read);
        //FileStream FS = new FileStream("Assets/World/Terrain/" + FileName, FileMode.Open, FileAccess.Read);
        int x;
        int y;
        float[,] HArray = new float[TRes, TRes];

        BinaryReader BR = new BinaryReader(FS);

        for (x = 0; x < TRes; x++)
        {
            for (y = 0; y < TRes; y++)
            {
                float Height = (float)(BR.ReadByte() / 50);
                HArray[x, y] = Height;
            }
        }

        return HArray;
    }
}

And the odd result:

bump

I need to do the same thing that is described here.
Has a solution been found?

Thanks!

-Aubrey

At least a couple of things seem to be wrong with that script. Firstly, if the file really is using 16-bit greyscale, then the using the BinaryReader’s ReadByte function wouldn’t give the right result (BinaryReader also has a ReadInt16 function, which would seem to be necessary here). Also, this line:-

float Height = (float)(BR.ReadByte() / 50);

…doesn’t actually do what it is supposed to. The result of ReadByte is an integer value and the 50 is an integer constant, so integer division will be performed on the value and only then will it be converted to float. The line should be something like:-

float Height = (float) BR.ReadByte() / 50f;

…although, as I have said, ReadByte probably isn’t the right function to use here.

EDIT:

Due to my train of thought leading me far beyond 16 bit image support, a new thread dedicated to terrain scripting has been created:

http://forum.unity3d.com/viewtopic.php?p=203280