Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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
0
Question by Ardan · Jun 29, 2011 at 06:04 PM · colorheightmapgradientgetpixelsgreyscale

Color a greyscale image using a gradient [SOLVED]

I asked this question on the forum aswell but i thought i might do it here as well.

FORUM THREAD

Lets say i have a heightmap(greyscale) and i want to apply color to it using a gradient, like they do on this site HERE, in the middle of the page.

I got an answer on the forum which pointed me in what I think is the right direction. He said that i should make my gradient texture 1 pixel wide and 256 pixels tall (FIRST PROBLEM) and then load both my heightmap and gradient into seperate color arrays using GetPixels. Next he gave me a line of code to use:

 for(var i=0; i<heightmapColors.Length; i++){
     heightmapColors[i]=gradientColors[heightmapColors[i].r];
 }

with this description: "read each pixel in your height map and replace it with a pixel that many bytes into the second array."

My problem is that when i try it his way i only end up with the lowest parts of the gradients color scale. Where 0.0 is blue and 256 is supposed to be grey (but now when the texture has to be 2x256 it is 512).

So my question is where do i go from here? And is there some other way to do this?

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

4 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by jester · Jun 29, 2011 at 06:36 PM

i haven't played with heightmaps yet, but my guess would be that if your heightmap doesn't span the entire range of its possible values, you'll only get the lowest color range from your gradient (or some contiguous band of color from within the gradient).

you could find the min/max height values you have in the heightmap and then normalize them from 0..1 and then multiply that by the number of colors in your gradient (256 for example) and then use those values when looking up the color. that should get you the entire range of colors from your gradient.

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 Ardan · Jun 29, 2011 at 07:31 PM

This is what i did, and the result isnt what i hoped for: using UnityEngine; using System.Collections; using System.IO;

 public class terrainmap : MonoBehaviour {
 
     public Texture2D heightmap;
     public Texture2D gradient;
     
     private Color[] heightmapColors;
     private Color[] gradientColors;    
     
     void  Start (){
         heightmapColors = heightmap.GetPixels(0);
         gradientColors = gradient.GetPixels(0);
         colorize();
     }
     
     void  colorize (){
         Texture2D image= new Texture2D(heightmap.width, heightmap.height,TextureFormat.RGB24, false);
     
         for(int i=0; i<heightmapColors.Length; i++){
             float he = heightmapColors[i].g;
             for(int j= 0; j<gradientColors.Length; j++) {
                 float gr = gradientColors[j].g;
                 if(he == gr) {
                     heightmapColors[i] = gradientColors[j];
                     heightmapColors[i].a = 1.0f;
                 }
             }
         }
         image.SetPixels(heightmapColors, 0);
         image.Apply();    
     
         byte[] bytes = image.EncodeToPNG();
         Destroy(image);
         File.WriteAllBytes("C:\\test.png", bytes);
     }
 }

And the result is this: Picture

Maybe i could make two gradients. One with the color, and that just goes from black to white. And then just take the cordinate of the current grey color and use the same position in the colored gradient?

Comment
Add comment · Show 2 · 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 jester · Jun 29, 2011 at 08:25 PM 1
Share

just so i understand better, are you trying to reproduce the effect in that linked page exactly?

it looks like with the getpixels function (http://unity3d.com/support/documentation/ScriptReference/Texture2D.GetPixels.html), you should use a gradient that is 256 pixels wide and 2 pixels tall. but when you go back to reference that for a color, you should still use 256 as your max color index, not 512. using numbers greater than 256 would have you wrapping around from the last color to the first one, and that's not the effect you want.

in your colorize function, using just the G channel of the heightmap colors is fine because the R, G and B channels should all be the same value, but that won't be the case in the colored gradient.

ins$$anonymous$$d, i think you want to do something like: - get the heightmap G channel value (a value from 0..1) - get a color index by multiply that by your max color number (256 for example) - get the color from your gradient array at the color index number from above (you'll have to round or mathf.floor() that value)

that way, all of the pixels in your heightmap that are at the same height value will all end up with the same color from the gradient.

avatar image Ardan · Jun 29, 2011 at 10:05 PM 0
Share

that did it, thanks!

avatar image
0

Answer by Ardan · Jun 29, 2011 at 10:17 PM

For anyone trying to figure this out aswell, here is my code:

 using UnityEngine;
 using System.Collections;
 using System.IO;
 
 public class terrainmap : MonoBehaviour {
 
     public Texture2D heightmap;
     public Texture2D gradientColor;
     
     private Color[] heightmapArray;
     private Color[] gradientArray;    
     
     void  Start (){
         heightmapArray = heightmap.GetPixels(0);
         gradientArray = gradientColor.GetPixels(0);
         colorize();
     }
     
     void  colorize (){
         Texture2D image= new Texture2D(heightmap.width, heightmap.height,TextureFormat.RGB24, false);
         
         for(int i=0; i<heightmapArray.Length; i++){
             float he = heightmapArray[i].b;
             int color = (int)(he * 255.0f);
             heightmapArray[i] = gradientArray[color];
         }
         image.SetPixels(heightmapArray, 0);
         image.Apply();
         Destroy(image);
         File.WriteAllBytes("C:\\test.png", image.EncodeToPNG());
     }
 }

this will generate THIS from THIS using THIS

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 Rs · Nov 30, 2015 at 11:30 AM

There's this free resource that could be very useful in this particular case. https://github.com/rstecca/ColorBands

This will give you the chance to create your own color bands as assets and call an Evaluate method to get the color at position t, being t=0 the leftmost color and t=1 the rightmost color. It's ideal to remap values between 0 and 1 to a sequence of colors. Just make sure you normalize your values before giving them in.

alt text


screenshot-01.png (10.0 kB)
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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Light bandings 0 Answers

Material doesn't have a color property '_Color' 4 Answers

Changing color of Texture2d with transparency 1 Answer

UI Text 2 Color Horizontal Fill With Sliding Dividing Line 0 Answers

Changing two different objects renderer colour 1 Answer


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