HeightmapFromTexture

From Unify Community Wiki
(Difference between revisions)
Jump to: navigation, search
(Removing all content from page)
m (Reverted edits by Joseph05408 (Talk); changed back to last version by Eric5h5)
Line 1: Line 1:
 +
[[Category:Editor Scripts]]
 +
[[Category:JavaScript]]
  
 +
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>

Revision as of 19:07, 19 October 2009


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