[PAID] Interpolate colors between vertex in a plane

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:

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:

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

        //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)

        // 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
                    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
                    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
                     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
                     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:

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!

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