Changing Color Based on Z position

Hi, all! I have a cube, and I would like to change its renderer.material.color from one RGB to another RGB In between two points on the Z-axis in space. For instance, if my start parameter is 1.0 on the Z axis and my starting color is yellow, and my ending color is red at 2.0 on the Z-axis, when the cube is at the start (1.0), it is yellow. At 1.5 on the Z-axis the cube will be orange, and at 2.0 on the Z-axis the cube will be red. So I am asking if anyone knows how to link an RGB value to a position and turn it into a percentile and plug it into the RGB value.

Thanks! Happy gaming!- YA

2 Answers

2

You could do it in a shader… if you want really accurate gradients on the object itself, and are willing to put excessive amounts of processing power into such a menial task.

Or, you could do it in a script and get a good looking result that’s considerably cheaper. Every Update() you want to get the objects position and use that to interpolate from one color to the other.

  1. Create a shader that takes an extra color parameter or just use the MainColor of a built-in one.

  2. Create a simple script that does something like this:

     var leftBoundCol : Color;
     var rightBoundCol : Color;
    
     var leftBound : float;
     var rightBound : float;
    
     function Update () {
             var lerpParam = Mathf.InverseLerp(leftBound, rightBound , transform.position.z);
             renderer.material.color = Color.Lerp(leftBoundCol , rightBoundCol , lerpParam);
     }
    

    I think everything in this is pretty self-explanatory. You set the endpoints, and the endpoint-colors. Then, based on the objects, position between the two endpoints, it assigns the main color of the object to be something in-between the two.

This in turn changes the color of the entire object. If you were to do it in a shader, you could get per vertex or even per fragment changes in color, but as I mentioned earlier, that is considerably more expensive.

Doing it via script is one lerp per frame. Doing it in a shader is at least as many vertices as you have per frame. So unless its a cube, assume a few hundred to a few thousand lerps per second.

Thank you. Haha luckily I am using cubes. I am going for a retro stye so they will only be one color. :) Last thing: What is a Lerp?

Lerp = Linear intERPolate. It linearly moves from the start value to the end value. There are a few ways of doing it, but here's and easy to understand way of explaining it: Actual Value = (1 - param) * initialValue + param * finalValue When the parameter is 0, we are at the initial value. When the parameter is 1, we are at the final value. and When its somewhere in-between, we're somewhere in-between.

Thank you very much. You have no idea how much help you have been! Thank you!

Off the top of my head, I think you would do something like this to blend between yellow and red based on a z-position between 1 and 2:

    renderer.material.color = Color.Lerp(
        Color.red, 
        Color.yellow, 
        2.0f - transform.position.z);