HeightmapFromTexture

From Unify Community Wiki
Revision as of 19:07, 19 October 2009 by NCarter (Talk | contribs)

Jump to: navigation, search


Author: Eric Haines (Eric5h5)

Description

Uses a texture in your project as a heightmap, which is applied to the active terrain. This way you don't have to import RAW files, but the vertical resolution will be limited to 8-bit.

Usage

You must place the script in a folder named Editor in your project's Assets folder for it to work properly.

To turn a texture into a heightmap, click on the texture in your project, then select the Heightmap From Texture item in the Terrain menu. The texture must be uncompressed to work. Textures with color are fine, since the colors are evaluated by their grayscale value. If the texture is a different size from the heightmap resolution, it will be resized to fit (internally--the actual texture is untouched). If the texture is resized, it will be scaled using simple nearest-neighbor scaling if the texture is set to have no filtering; otherwise it will be scaled using bilinear filtering.

JavaScript - HeightmapFromTexture.js

<javascript> @MenuItem ("Terrain/Heightmap From Texture")

static function ApplyHeightmap () { var heightmap : Texture2D = Selection.activeObject as Texture2D; if (heightmap == null) { EditorUtility.DisplayDialog("No texture selected", "Please select a texture.", "Cancel"); return; } if (heightmap.format != TextureFormat.ARGB32 && heightmap.format != TextureFormat.RGB24 && heightmap.format != TextureFormat.Alpha8) { EditorUtility.DisplayDialog("Wrong format", "Texture must be uncompressed (RGBA 32 bit, RGB 24 bit, or Alpha 8 bit)", "Cancel"); return; } var terrain = Terrain.activeTerrain.terrainData; Undo.RegisterUndo(terrain, "Heightmap From Texture"); var w = heightmap.width; var h = heightmap.height; var w2 = terrain.heightmapWidth; var h2 = terrain.heightmapHeight; var heightmapData = terrain.GetHeights(0, 0, w2, h2); var mapColors = heightmap.GetPixels(); var map = new Color[w2 * h2];

if (w2 != w || h != w) { // Resize using nearest-neighbor scaling if texture has no filtering if (heightmap.filterMode == FilterMode.Point) { var dx : float = parseFloat(w)/w2; var dy : float = parseFloat(h)/h2; for (y = 0; y < h2; y++) { if (y%20 == 0) { EditorUtility.DisplayProgressBar("Resize", "Calculating texture", Mathf.InverseLerp(0.0, h2, y)); } var thisY = parseInt(dy*y)*w; var yw = y*h2; for (x = 0; x < w2; x++) { map[yw + x] = mapColors[thisY + dx*x]; } } } // Otherwise resize using bilinear filtering else { var ratioX = 1.0/(parseFloat(w2)/(w-1)); var ratioY = 1.0/(parseFloat(h2)/(h-1)); for (y = 0; y < h2; y++) { if (y%20 == 0) { EditorUtility.DisplayProgressBar("Resize", "Calculating texture", Mathf.InverseLerp(0.0, h2, y)); } var yy = Mathf.Floor(y*ratioY); var y1 = yy*w; var y2 = (yy+1)*w; yw = y*h2; for (x = 0; x < w2; x++) { var xx = Mathf.Floor(x*ratioX);

var bl = mapColors[y1 + xx]; var br = mapColors[y1 + xx+1]; var tl = mapColors[y2 + xx]; var tr = mapColors[y2 + xx+1];

var xLerp = x*ratioX-xx; map[yw + x] = Color.Lerp(Color.Lerp(bl, br, xLerp), Color.Lerp(tl, tr, xLerp), y*ratioY-yy); } } } EditorUtility.ClearProgressBar(); } else { // Use original if no resize is needed map = mapColors; }

for (y = 0; y < h2; y++) { for (x = 0; x < w2; x++) { heightmapData[y,x] = map[y*w2+x].grayscale; } } terrain.SetHeights(0, 0, heightmapData); } </javascript>

Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox