# How to add color for 3d terrain

hi

i need help

how to make colors like this ??

1 Like

HSB color mode is what you are looking for
https://processing.org/reference/colorMode_.html

1 Like

Hello,

Take a look at this example:
RGBCube \ Examples \ Processing.org

Think about how to apply this to the terrain code.

Consider mapping colors to one of the axes and apply that to a vertex.

Other references for color:

`:)`

Update:

I followed my initial vision and tried this:

HSB colorMode was used.

Have fun!

@glv

hi

this is the most i can get but not what i want i want to color the mesh where i want to choose certain xyz and color it

``````import peasy.*;
PeasyCam cam;
int cols, rows, s;
int w, h;

float inc=0.12;

color one=color(50, 150, 3);
color tow=color(222, 5, 10,123);
color white=color(255);
color cyan=color(0, 90, 90);
color blue=color(0, 0, 70);

void setup() {
size(600, 600, P3D);
s=13;
w=900;
h=900;
cols=w/s;
rows=h/s;
cam=new PeasyCam(this, 400, 400, 200, 700);
}

void draw() {
lights();
background(233);

pushMatrix();
translate(0, height*0.3, -100);
rotateX(PI/3);

// noStroke();
stroke(12);
float yoff=0;

for (int y=0; y<rows; y++) {
beginShape(TRIANGLE_STRIP);
float xoff=0;

for (int x=0; x<cols; x++) {

float z=map(noise(xoff, yoff), 0, 1, -60, 410);
yoff+=inc;
float z2=map(noise(xoff, yoff), 0, 1, -60, 410);
yoff-=inc;

colorMode(HSB);
float n=noise(xoff+1, yoff+1);
float t =map(n, 0, 1, 0, hue(tow)*2);
float kL=map(n, 0, 1, 0, hue(one)*2);
color gd=color(constrain(t, 0, hue(tow)), saturation(one), brightness(tow));
color gl=color(constrain(kL, 0, hue(tow)), saturation(one), brightness(one));
colorMode(RGB);

if (z>225) {
fill(lerpColor(gl, white, map(z, 25, 40, 0, 1)));
} else if (z>-25) {
fill(lerpColor(gd, gl, map(z, -25, 25, 0, 1)));
} else if (z>-40) {
fill(gd);
} else {
z=-140;
z2=-40;
fill(cyan);
}

vertex(x*s, y*s, z);
vertex(x*s, (y+1)*s, z2);
xoff+=inc;

}

yoff+=inc;

endShape();

}
popMatrix();
}

``````

Hello,

I modified a Processing example to change color along x-axis:

``````// Modified this:
// https://processing.org/examples/bounce.html
// See //glv in comments for changes\additions

int rad = 60;        // Width of the shape
float xpos, ypos;    // Starting position of shape

float xspeed = 5;  // Speed of the shape  //glv changed speed
float yspeed = 5;  // Speed of the shape  //glv changed speed

int xdirection = 1;  // Left or Right
int ydirection = 1;  // Top to Bottom

int hue;  //glv added

void setup()
{
size(640, 360);
noStroke();
frameRate(30);
// Set the starting position of the shape
xpos = width/2;
ypos = height/2;

hue = width;                   //glv added
colorMode(HSB, hue, 100, 100); //glv added
}

void draw()
{
background(102);

// Update the position of the shape
xpos = xpos + ( xspeed * xdirection );
ypos = ypos + ( yspeed * ydirection );

// Test to see if the shape exceeds the boundaries of the screen
// If it does, reverse its direction by multiplying by -1
if (xpos > width-rad || xpos < rad) {
xdirection *= -1;
}
if (ypos > height-rad || ypos < rad) {
ydirection *= -1;
}

// Draw the shape
fill(xpos, 100, 100); //glv added
}

``````

@jafal You should clean up your code before posting. Too many blank lines.

`:)`

1 Like

but here z and z2 should have the same value, right?

@glv
hi
do you mean that determine x y then map as fill ?

hi
no matter if they same or not i want to apply the color i choose to demand area of the mesh

my apologies. My remark was just a side note. I think when z is not equal z2, the mesh has holes.

just to give you some idea of the logic

here is a perlin terrain sketch in 2d

``````float xn,yn,zn;

long n;
int gridSize = 10;
int numCircles = floor(500/gridSize * 500/gridSize);
int cols,rows;

Circle[] circles;
boolean wrap = true;

void setup(){

size(500,500,FX2D);

cols = 250;
rows = 250;

float w = (width/cols);
float h = (height/rows);

circles = new Circle[cols*rows];

for (int y = 0; y < rows; y++){
for (int x = 0; x < cols; x++){

int pos = x + y * cols;
circles[pos] = new Circle(pos,0+w*x,h*y,w,h);

}}
n = (long)random(10000);

zn = noise(n);
};

void draw(){
background(255,255,255);
clear();
Perlin();
fill(255,255,0);
text(frameRate,10,10);
};

int inc = 0;
float mult = 0.05;

void Perlin(){

xn=noise(n);
yn=noise(n);

int startc = 1;if(wrap) startc = 0;
int endc = cols-1;if(wrap) endc = cols;

int startr = 1;if(wrap) startr = 0;
int endr = rows-1;if(wrap) endr = rows;

inc ++;

for (int y = startr; y  < endr;y++){

yn+=mult;
zn+=mult/4000;
xn=0;

for (int x = startc; x < endc; x++){

xn+=mult;

float rs = noise(xn,yn,zn)*15;
int pos = x + y * cols;

circles[pos].colour = color(100*rs/10, 100*rs/10, 100*rs/10);
circles[pos].c = color(100*rs/10, 100*rs/10, 100*rs/10);
if(brightness(circles[pos].colour) < 50){
circles[pos].c = color(0, 255, 0);
circles[pos].colour = color(0, 255, 0);
}
else{ circles[pos].c = color(255,0,0);
circles[pos].colour = color(255,0,0);
}

if(neighbouringCells(x, y, pos)==1) circles[pos].c = color(0,0,255);
else if(neighbouringCells(x, y, pos)==0) circles[pos].c = circles[pos].colour;;

circles[pos].Display();
}
}

};

int neighbouringCells(int x, int y, int cellToCheck){

color c = circles[cellToCheck].colour;

//int cols = 500/gridSize;
//int rows = 500/gridSize;

int l = (x-1) + y * cols;
if(x==0&&wrap)l = (cols-1) + y * cols;
color lc = circles[l].colour;
int tl = (x-1) + (y - 1) * cols;
if(x==0&&y!=0&&wrap)tl = (cols-1) + y * cols;
if(y==0&&x!=0&&wrap)tl = (x-1) + (rows-1) * cols;
if(y==0&&x==0&&wrap)tl = (cols-1) + (rows-1) * cols;
color tlc = circles[tl].colour;
int t = (x) + (y - 1) * cols;
if(y==0&&wrap)      t = (x-1) + (rows-1) * cols;
color tc = circles[t].colour;
int tr = (x + 1) + (y - 1) * cols;
if(x==cols-1&&y!=0&&wrap)tr = (0) + y * cols;
if(y==0&&x!=cols-1&&wrap)tr = (x-1) + (rows-1) * cols;
if(y==0&&x==cols-1&&wrap)tr = (0) + (rows-1) * cols;
color trc = circles[tr].colour;
int r = (x+1) + (y) * cols;
if(x==cols-1&&wrap)r = (0) + y * cols;
color rc = circles[r].colour;
int br = (x+1) + (y+1) * cols;
if(y!=rows-1&&x==cols-1&&wrap) br = (0) + y * cols;
else if(y==rows-1&&x!=cols-1&&wrap) br = (x+1) + (0) * cols;
else if(y==rows-1&&x==cols-1&&wrap) br = (0) + (0) * cols;
color brc = circles[br].colour;
int b = (x) + (y+1) * cols;
if(y==rows-1&&wrap)b = (cols-1) + (rows-1) * cols;
color bc = circles[b].colour;
int bl = (x-1) + (y+1) * cols;
if(x==0&&y!=rows-1&&wrap)bl = (cols-1) + y * cols;
if(y==rows-1&&x!=0&&wrap)bl = (x-1) + (0) * cols;
if(y==rows-1&&x==0&&wrap)bl = (cols-1) + (0) * cols;
color blc = circles[bl].colour;;

if(lc!=c||tlc!=c||tc!=c||trc!=c||rc!=c||brc!=c||bc!=c||blc!=c)return 1;
else return 0;

};

``````
``````public class Circle {
//int xPos,yPos,dim,dim2,id,x,y; // location // dimension
float xPos,yPos,dim,dim2,id,x,y;
color colour = color(255,255,255),c; // color

// Circle(int xPos, int yPos,int dim,int dim2,color colour) {
//  this.xPos = xPos;
//  this.yPos = yPos;
//  this.dim = dim;
//  this.dim2 =dim2;
//  this.colour = colour;
//}

Circle(int id,float xPos, float yPos) {
this.id = id;
this.x = xPos;
this.y = yPos;
this.dim = gridSize;
this.dim2 = gridSize;
this.colour = colour;
}

Circle(int id,float xPos, float yPos,float w,float h) {
this.id = id;
this.x = xPos;
this.y = yPos;
this.dim = w;
this.dim2 = h;
this.colour = colour;
}
void Display(){
fill(c);
noStroke();
//text(id,x,y);
rect(x,y,dim,dim2);
// println(colour);

}
}

``````

as simple as possible

``````// Daniel Shiffman
// http://codingtra.in
// http://patreon.com/codingtrain
// Code for: https://youtu.be/IKB1hWWedMk

int cols, rows;
int scl = 20;
int w = 2000;
int h = 1600;

float flying = 0;

float[][] terrain;

void setup() {
size(600, 600, P3D);
cols = w / scl;
rows = h/ scl;
terrain = new float[cols][rows];
}

void draw() {
background(0);
stroke(255);
noFill();
//flying -= 0.1;

float yoff = flying;
for (int y = 0; y < rows; y++) {
float xoff = 0;
for (int x = 0; x < cols; x++) {
terrain[x][y] = map(noise(xoff, yoff), 0, 1, 0, 255);

xoff += 0.2;
//float d = map(terrain[x][y],-255,255,0,255);;
color c = 0;
//println(terrain[x][y]);
if(terrain[x][y]<60)c = color(0,0,255);
if(terrain[x][y]>60)c = color(189, 189, 23);
if(terrain[x][y]>100)c = color(31, 138, 29);
if(terrain[x][y]>160)c = color(84, 94, 84);
if(terrain[x][y]>200)c = color(255);
noStroke();
fill(c);
rect(x*scl,y*scl,scl,scl);
}
yoff += 0.2;
}

};
``````

do note that this will only produce simple maps. To create more realistic map, you need to make use of octaves frequency, amplitude and lacunarity.

See sebastian lague on youtube for in depth perlin noise class.

1 Like

thanks for you time and answer i have used same style above

``````  if(terrain[x][y]<60)c = color(0,0,255);
if(terrain[x][y]>60)c = color(189, 189, 23);
``````

and this is the result

but what i need to determined the x Y position and color it or give it color without if X or if Y

thanks for you care

it is great link thanks a lot

The trick is to establish different heights for different terrain types or colors

There are lots of great sketches with perlin terrain on this forum too.

i know that the noise gives variable z points by using that you can make colors …but for accurate measurements tricks wont be useful Which is why its often recommended to normalise the values, this also helps with tiling. This however requires you itterate using two separate loops. The first to establish min height and max height and the second time to assign the colors as per your creative preference.

have a look for this using the same trick color the z noise but it is just 5\$ spectrum analyzer ! in electronics this is the noise meaning

Here you can scale the Z-color
Blue for water for green for grass, brown for heights, etc.