MackeyK24 Posted November 27, 2016 Share Posted November 27, 2016 I need some help with color math. I am trying to create height maps in code... i can read raw terrain data and get the float raw height value for each pixel (x,y) as a value from 0 to 1 0 being black and 1 being white. I need to convert that 0 to 1 float to a black and white pixel based on the level of 0 to 1. Here is an example code block.. I need to basically create a Color.FromFloat type function as listed below: Texture2D duplicateHeightMap = new Texture2D(terrain.terrainData.heightmapWidth, terrain.terrainData.heightmapHeight, TextureFormat.ARGB32, false); float[,] rawHeights = terrain.terrainData.GetHeights(0, 0, terrain.terrainData.heightmapWidth, terrain.terrainData.heightmapHeight); /// run through the array row by row for (int y=0; y < duplicateHeightMap.height; y++) { for (int x=0; x < duplicateHeightMap.width; x++) { // height map color (0 to 1) float rawHeight = rawHeights[x, y]; // NOTE: HERE IS WHERE I NEED HELP (MAYBE GRAYSCALE ???) Color color = Color.FromFloat(rawHeight); duplicateHeightMap.SetPixel(x, y, color); } } // Apply all SetPixel calls duplicateHeightMap.Apply(); Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted November 27, 2016 Author Share Posted November 27, 2016 Should this work: Color color = new Color(rawHeight * 255.0f, rawHeight * 255.0f, rawHeight * 255.0f, 1.0f); Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted November 28, 2016 Share Posted November 28, 2016 This should work if rawheight is between 0 and 1 Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted November 29, 2016 Author Share Posted November 29, 2016 If you are familiar with the exporter code... Check out this enhancement for support native unity terrains (Note how i read the terrains raw heights... then create a height map based on the height values and use a darkness level to factor the level of darkness of the calculated grayscaled color channels): private BabylonMesh ConvertUnityTerrainToBabylon(Terrain terrain, GameObject gameObject, ref UnityMetaData metaData, ref List<BabylonExport.Entities.BabylonParticleSystem> particleSystems, ref List<UnityFlareSystem> lensFlares, ref string componentTags) { BabylonMesh babylonMesh = new BabylonMesh { name = gameObject.name, id = GetID(gameObject) }; metaData.type = "Terrain"; babylonMesh.tags = componentTags; babylonMesh.tags += " [TERRAIN]"; if (!String.IsNullOrEmpty(babylonMesh.tags)) { babylonMesh.tags = babylonMesh.tags.Trim(); } ExporterWindow.ReportProgress(1, "Parsing terrain: " + gameObject.name); var transform = gameObject.transform; babylonMesh.parentId = GetParentID(transform); babylonMesh.position = transform.localPosition.ToFloat(); babylonMesh.rotation = new float[3]; babylonMesh.rotation[0] = transform.localRotation.eulerAngles.x * (float)Math.PI / 180; babylonMesh.rotation[1] = transform.localRotation.eulerAngles.y * (float)Math.PI / 180; babylonMesh.rotation[2] = transform.localRotation.eulerAngles.z * (float)Math.PI / 180; babylonMesh.scaling = transform.localScale.ToFloat(); babylonMesh.isVisible = false; babylonMesh.visibility = 0; babylonMesh.checkCollisions = false; // Terrain var generator = gameObject.GetComponent<BabylonTerrainGenerator>(); if (terrain != null && generator != null) { bool png = (exportationOptions.DefaultImageFormat == (int)BabylonImageFormat.PNG); string fext = (png == true) ? ".png" : ".jpg"; metaData.properties.Add("width", terrain.terrainData.size.x); metaData.properties.Add("length", terrain.terrainData.size.z); metaData.properties.Add("height", terrain.terrainData.size.y); metaData.properties.Add("detailWidth", terrain.terrainData.detailWidth); metaData.properties.Add("detailHeight", terrain.terrainData.detailHeight); metaData.properties.Add("heightmapWidth", terrain.terrainData.heightmapWidth); metaData.properties.Add("heightmapHeight", terrain.terrainData.heightmapHeight); metaData.properties.Add("minimumHeightLevel", generator.minimumHeightLevel); metaData.properties.Add("maximumHeightLevel", generator.maximumHeightLevel); metaData.properties.Add("groundTessellation", generator.groundTessellation); if (generator.terrainSurfaceMaterial != null) { var mat = DumpMaterial(generator.terrainSurfaceMaterial); metaData.properties.Add("surfaceMaterialId", mat.id); } else { metaData.properties.Add("surfaceMaterialId", null); } float[,] rawHeights = terrain.terrainData.GetHeights(0, 0, terrain.terrainData.heightmapWidth, terrain.terrainData.heightmapHeight); if (generator.terrainMode == BabylonTerrainMode.HeightMap) { ExporterWindow.ReportProgress(1, "Generating terrain heightmap: " + gameObject.name); Texture2D heightMap = new Texture2D(terrain.terrainData.heightmapWidth, terrain.terrainData.heightmapHeight, TextureFormat.ARGB32, false); for (int y=0; y < heightMap.height; y++) { for (int x=0; x < heightMap.width; x++) { float height = rawHeights[x, y]; float gray = (0.2126f * height * 255.0f) + 0.7152f * (height * 255.0f) + 0.0722f * (height * 255.0f); gray = gray / generator.heightmapDarkness; Color color = new Color(gray, gray, gray, 1.0f); heightMap.SetPixel(x, y, color); } } heightMap.Apply(); string tempFilename = "temp" + terrain.name.Replace(" ", "").Replace("(", "").Replace(")", "") + "Heightmap" + fext; string tempTexturePath = Path.Combine(Application.dataPath.Replace("/Assets", "/Temp/data"), tempFilename); string heightmapEncoding = (png) ? "data:image/png;base64," : "data:image/jpg;base64,"; byte[] heightmapBytes = (png) ? heightMap.EncodeToPNG() : heightMap.EncodeToJPG(exportationOptions.DefaultQualityLevel); metaData.properties.Add("heightmapBase64", (heightmapEncoding + Convert.ToBase64String(heightmapBytes))); string temp = Path.GetDirectoryName(tempTexturePath); if (!Directory.Exists(temp)) Directory.CreateDirectory(temp); File.WriteAllBytes(tempTexturePath, heightmapBytes); } else { babylonMesh.isVisible = true; babylonMesh.visibility = 1; babylonMesh.checkCollisions = true; ExporterWindow.ReportProgress(1, "Generating terrain mesh: " + gameObject.name); } } babylonMesh.metadata = metaData; babylonScene.MeshesList.Add(babylonMesh); // Animations ExportAnimations(transform, babylonMesh); if (IsRotationQuaternionAnimated(babylonMesh)) { babylonMesh.rotationQuaternion = transform.localRotation.ToFloat(); } // Lens Flares ParseLensFlares(gameObject, babylonMesh.id, ref lensFlares); // Particles Systems ParseParticleSystems(gameObject, babylonMesh.id, ref particleSystems); return babylonMesh; } Then in the unity loader i create the actual ground like this: // Parse scene native mesh and heightmap terrains var terrains:BABYLON.Mesh[] = this._scene.getMeshesByTags("[TERRAIN]"); if (terrains != null) { terrains.forEach((terrain)=>{ if (terrain.metadata != null && terrain.metadata.properties != null) { if (terrain.metadata.properties.heightmapBase64) { var tempBase64:string = terrain.metadata.properties.heightmapBase64; var terrainWidth:number = terrain.metadata.properties.width; var terrainLength:number = terrain.metadata.properties.length; var terrainHeight:number = terrain.metadata.properties.height; var minimumHeightLevel:number = terrain.metadata.properties.minimumHeightLevel; var maximumHeightLevel:number = terrain.metadata.properties.maximumHeightLevel; var groundTessellation:number = terrain.metadata.properties.groundTessellation; var surfaceMaterialId:string = terrain.metadata.properties.surfaceMaterialId; var surfaceMaterialInst:BABYLON.Material = null; if (surfaceMaterialId != null && surfaceMaterialId !== "") { var material:BABYLON.Material = this._scene.getMaterialByID(surfaceMaterialId); surfaceMaterialInst = material; } BABYLON.MeshBuilder.CreateGroundFromHeightMap((terrain.name + "_Mesh"), tempBase64, { width: terrainWidth, height: terrainLength, subdivisions: groundTessellation, minHeight: minimumHeightLevel, maxHeight: maximumHeightLevel, updatable: true, onReady: (mesh:BABYLON.Mesh) => { mesh.parent = terrain; mesh.scaling = terrain.scaling.clone(); mesh.position.x -= terrain.position.x; mesh.position.z -= terrain.position.z; mesh.checkCollisions = true; if (surfaceMaterialInst != null) { mesh.material = surfaceMaterialInst; } } }, this._scene); } else { // TODO: Native Mesh - Note should try do all c# editor side } } }); } You gotta luv that metadata i added Note: Although i get VERY SLOW and CHOPPY movement using the activeCamera.attachControl for user input. Also brings fps down about 15fps soon as you start moving on the created found terrain... Ever heard of that ??? Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted November 29, 2016 Share Posted November 29, 2016 I'am already loving it But I can't wait to see your PR Quote Link to comment Share on other sites More sharing options...
Wingnut Posted November 30, 2016 Share Posted November 30, 2016 8 hours ago, MackeyK24 said: Although i get VERY SLOW and CHOPPY movement using the activeCamera.attachControl for user input. Also brings fps down about 15fps soon as you start moving on the created found terrain... Ever heard of that ??? Hi again MK24! You're kickin' good butt, as always. Nice work. Do you know about "profiling" in the browser's dev tools area? I haven't used it much at all, but rumor says you can easily find what is bogging-down a scene. *shrug* Any chance you can reproduce the symptom in a playground scene? That might tell more. Quote Link to comment Share on other sites More sharing options...
MrVR Posted December 2, 2016 Share Posted December 2, 2016 Nice @MackeyK24 this is crazy amazing jajaja, hey do you have any idea or an estimate date for the release of the API? Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted December 2, 2016 Author Share Posted December 2, 2016 Yeah... i think the ground subdivisions was set too high Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.