# \[PAID\] Interpolate colors between vertex in a plane

**URL:** <https://discourse.threejs.org/t/paid-interpolate-colors-between-vertex-in-a-plane/33562>\
**Category:** Jobs\
**Tags:** plane-geometry, vertex-colors, biomes, procedural\
**Created:** [January 12, 2022, 6:10pm UTC](https://discourse.threejs.org/t/paid-interpolate-colors-between-vertex-in-a-plane/33562 "2022-01-12T18:10:22Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![LourentsVlogs](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/lourentsvlogs/32/21198_2.png) [@LourentsVlogs](https://discourse.threejs.org/u/LourentsVlogs)\
**Post date:** [January 12, 2022, 6:10pm UTC](https://discourse.threejs.org/t/paid-interpolate-colors-between-vertex-in-a-plane/33562/1 "2022-01-12T18:10:22Z")

</div>

So I have this plane generated with two different Perlin noises. It has mainly 3 regions, divided by color. I want to smooth out the lines, to create a “gradient” so there are no abrupt color changes:

 ![image](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/f/6/f6830ca642ae97f20c878ac77afbb2a584b02961.png)

Each zone corresponds to a biome which is decided by a PerlinNoise called Humidity and another one called Temperature, so each vertex receives a biome according to the following chart with its corresponding humidity and temperature vertices’ height:  
 ![image](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/e/a/ea224d1af16bcb6f4f2080d903fa804b3414a022.png)

So this is my code (I commented almost every step):

```javascript
        //CREATES the terrain material and geometry + adds the color attribute
        let TerrainMaterial = new THREE.MeshPhongMaterial({side:THREE.DoubleSide, flatShading: true,vertexColors: true});
        let TerrainGeometry = new THREE.PlaneGeometry(step, step, 16,16);
        TerrainGeometry.setAttribute( 'color', new THREE.BufferAttribute( new Float32Array( TerrainGeometry.attributes.position.count * 3), 3 ) )
        const colors = TerrainGeometry.attributes.color;

        //The position like this is to create a grid so every tile is next to eachother
        let terrain = new THREE.Mesh(TerrainGeometry,TerrainMaterial)
        terrain.position.set(x, 0, z).multiplyScalar(step)
        this.experience.scene.add(terrain)

        // Create some variables
        const TemperatureVertices = TemperatureTerrain.attributes.position;
        const HumidityVertices = HumidityTerrain.attributes.position;
        let pos = TerrainGeometry.attributes.position;

        const lerp = (a, b, amount) => (1 - amount) * a + amount * b;

         //iteration through each vertex
        for(let i = 0; i < pos.count; i++){

            //gets temperature and humidity maps vertex height
           let temperature = TemperatureVertices.getY(i) * 2;
           let humidity = HumidityVertices.getY(i)* 2;

           //this function returns the biome according with the chart in the post by giving it temperature and humidity variables
           let BIOME = this.Biomes.determineBiome(temperature,humidity,new THREE.Vector2(x, z),i);
        
           //This retrieves the fractional part of the numer, ex: frac(-2.8) = 0.8 or frac(10.09) = 0.9
           var a = Math.abs(temperature) - Math.floor(Math.abs(temperature))
           var b = Math.abs(humidity) - Math.floor(Math.abs(humidity))

           //This variables determine the "blending zone", wich you will understand later
           let AMPLIFIER = 0.1;
           let AMPLIFIER1 = 0.9;

           //Instantiates the temperature and humidity variables
           let temperature_blending = temperature;
           let temperature_weight = 1;

           let humidity_blending = humidity;
           let humidity_weight = 1;

           //This is executed if the temperature is close to the next biome chart row/column
            if(a < AMPLIFIER){
                //This algorithm gives me like a percentage of how much the vertex is influenced by the other biome.
                let x = Math.abs(temperature);
                temperature_weight = (x - Math.floor(x)) / AMPLIFIER

                //here based on the temperature, I can detect what is the closer column-
                if(temperature > 0){
                    temperature_blending -= 0.5
                }else{
                    temperature_blending += 0.5
                }
                //here I repeat the process but backwards as my function has to work with negative numbers when the closest biome column is further away than the original one.
            }else if(a > AMPLIFIER1){
                let x = -Math.abs(temperature);
                temperature_weight = (x - Math.floor(x)) / AMPLIFIER

                if(temperature < 0){
                    temperature_blending -= 0.5
                }else{
                    temperature_blending += 0.5
                }
            }
            
            //here I repeat all the process but for humidity
             if(b < AMPLIFIER){
                 let x = Math.abs(humidity);
                 humidity_weight = (x - Math.floor(x)) / AMPLIFIER
            
                 if(humidity > 0){
                     humidity_blending -= 0.5
                 }else{
                     humidity_blending += 0.5
                 }
             }else if(b > AMPLIFIER1){
                 let x = -Math.abs(humidity);
                 humidity_weight = (x - Math.floor(x)) / AMPLIFIER
            
                 if(humidity < 0){
                     humidity_blending -= 0.5
                 }else{
                     humidity_blending += 0.5
                 }
             }
            

            //Once we get here, We have the original vertex biome and the closest biome to it (if it is in the blending zone: very close to another biome implying that it has to start blending with it)
           let BIOME1 = this.Biomes.determineBiome(temperature_blending,humidity_blending,new THREE.Vector2(x, z),i);

                //I am very lost from here, I also think that the way to calculate the weights is incorrect.

           //this calculate the average between both climatic factors 
           let average = (humidity_weight+temperature_weight)/2

           //Here I try blending the colors between them using the average 
           colors.setXYZ( i, lerp(BIOME.color.r,BIOME1.color.r,average), lerp(BIOME.color.g,BIOME1.color.g,average), lerp(BIOME.color.b,BIOME1.color.b,average));
        }

```

The result which doesn’t look well:

 ![image](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/a/2/a20b740b18ef027439575cf7f3fb9463863f53c4.jpeg)

UPDATE: The problem is when I try to get the blending zone that I am doing something wrong.

So if you know how I can correct it, or if an algorithm already exists please tell me. Thanks a lot!

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/2X/c/c74c5243388bbfa21a39c3e824ddba702a623dec.png) [@system](https://discourse.threejs.org/u/system)\
**Post date:** [February 11, 2022, 6:10pm UTC](https://discourse.threejs.org/t/paid-interpolate-colors-between-vertex-in-a-plane/33562/2 "2022-02-11T18:10:41Z")

</div>

This topic was automatically closed after 29 days. New replies are no longer allowed.
