# 3D Perlin noise in Processing

**URL:** <https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770>\
**Category:** Coding Questions\
**Created:** [June 30, 2022, 6:05pm UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770 "2022-06-30T18:05:32Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![asymmetric](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/asymmetric/32/16577_2.png) [@asymmetric](https://discourse.processing.org/u/asymmetric)\
**Post date:** [June 30, 2022, 6:05pm UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/1 "2022-06-30T18:05:32Z")

</div>

Hello!

I just finished the coding train’s coding challenge #11 : 3D generation with perlin noise on YouTube! I have a question. How would I make a similar image but with my own image of noise that is responsive to the grid in the same way? I’ve been taking screenshots of loading imagery and I would like to have a sculptural 3D grid which responds to my own image of noise rather than random.

Thank you for your help! 👾🫠💛✨

Here is the code that I have at the moment without the image!

```auto
//VARIABLES
int cols,rows;
int scl = 8; //scale
int w = 1200;
int h = 900;

float[][] terrain;

//INITIALIZE
void setup(){
  size(1000,1000, P3D);  
  cols = w/ scl;  
  rows = h/ scl;
  terrain = new float [cols][rows];
  float yoff = 0;
  for (int y = 0; y < rows; y++) {
    float xoff = 0.2;
    beginShape(TRIANGLE_STRIP);
    for (int x = 0; x< cols; x++) {   
      terrain[x][y] = map(noise(xoff,yoff), 0, 1, -200, 50);
      xoff += 0.2;
    }
    yoff += 0.1;
  }
  
} 

void draw(){
  background(0);
  stroke(255);
  smooth();
  noFill(); 
  //rect(x*scl, y*scl, scl, scl); // grid!!
  
  translate(width/2, height/2); //rotate perspective
  //rotateX(PI/3); //rotate perspective
  translate(-width/2,-height/2); //perspective 
 
  
  frameRate(1);
  
  for (int y = 0; y < rows-1; y++) {
    beginShape(QUAD_STRIP); // OR beginShape(QUAD_STRIP), (TRIANGLE_STRIP)
    for (int x = 0; x< cols; x++) {
      vertex(x*scl, y*scl, terrain[x][y]);
      vertex(x*scl, (y+1)*scl, terrain[x][y+1]);
      
       }
         endShape();
    }
}

```

---

<div class="post-metadata">

**Author:** ![mnse](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mnse/32/16520_2.png) [@mnse](https://discourse.processing.org/u/mnse)\
**Post date:** [June 30, 2022, 6:36pm UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/2 "2022-06-30T18:36:25Z")

</div>

Hi @asymmetric,

Would you please [Format your code](https://discourse.processing.org/faq#format-your-code)

Some time ago I made an example for another post which uses a grid reacting on the underlying noise value by sizing the cells depending on that noise value. Maybe it gives you an idea which helps you. [Here](https://discourse.processing.org/t/dividing-a-grid-into-sections-using-noise/36127/3)

Cheers  
— mnse

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [June 30, 2022, 8:44pm UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/3 "2022-06-30T20:44:34Z")

</div>

Hello @asymmetric ,

Take a look at the code that you posted.

Please edit your post and format and post code as per here:  
[https://discourse.processing.org/faq#format-your-code](https://discourse.processing.org/faq#format-your-code)

Take a look at this tutorial:

> **[Images and Pixels](https://processing.org/tutorials/pixels/)**
>
> How to load and display images as well as access their pixels.

You can get information about each pixel in your image and use that to generate vertices.

Consider brightness.

> **[Brightness pixels / Examples](https://processing.org/examples/brightnesspixels.html)**
>
> This program adjusts the brightness of a part of the image by calculating the distance of each pixel to the mouse.

`:)`

---

<div class="post-metadata">

**Author:** ![asymmetric](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/asymmetric/32/16577_2.png) [@asymmetric](https://discourse.processing.org/u/asymmetric)\
**Post date:** [June 30, 2022, 8:49pm UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/4 "2022-06-30T20:49:31Z")

</div>

Hi MNSE! Thank you! That is defiantly very cool and I will try this code today! But I would like to have the grid react to a static image of noise rather than random numbers. I love the aesthetic of the black and white grid in the Perlin noise tutorial, but I would like to use an image that reacts to the grid. Here are some images that describe what I am looking for more clearly.

 ![Jan24](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/1/9/197e092f76e500102658c4476b09ae28ecd4ca36.jpeg)  
 ![Screen Shot 2022-06-29 at 4.28.28 PM](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/6/b/6b2098139e115e737979d89807296aabb85fb117.jpeg)

Can I use an image to create a similar interaction?  
`img = loadImage("Jan24.jpg");`

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [June 30, 2022, 9:48pm UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/5 "2022-06-30T21:48:58Z")

</div>

Hello @asymmetric,

> [@asymmetric](#):
>
> Can I use an image to create a similar interaction?  
> `img = loadImage("Jan24.jpg");`

Absolutely!

I merged your code with some snippets from the tutorial and voila!

To get you started:

```auto
  img = loadImage("avatar_cool.png");
  terrain = new float [img.width][img.height];
  img.loadPixels();
  for (int x = 0; x < img.width; x++) 
    {
    // Loop through every pixel row
    for (int y = 0; y < img.height; y++) 
      {
      // Use the formula to find the 1D location
      int loc = x + y * img.width;
      
      int bright = int(brightness(img.pixels[loc]));
      terrain[x][y] = bright;
      }
    }
img.updatePixels(); //Not needed here

```

![avatar_cool](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/a/3/a368a61d9c0fb1f23144266becd3b921124ad750.png)

Result:

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/8/7/87a39d7aaf64902dcdb206d0535d34553ec9b374.png)

Have fun!

`:)`

---

<div class="post-metadata">

**Author:** ![asymmetric](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/asymmetric/32/16577_2.png) [@asymmetric](https://discourse.processing.org/u/asymmetric)\
**Post date:** [July 1, 2022, 12:09am UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/7 "2022-07-01T00:09:21Z")

</div>

One more question. I am very new to Processing and I am studying/reading the handbook every day, but I don’t completely understand the structure of the code quite yet!

With that said, where would I plug the code that you sent me? I entered it under the void setup(); but I keep getting errors. If you would not mind uploading the full code that you used to get to that image, I would be immensely grateful! Thank you so much glv!!!

---

<div class="post-metadata">

**Author:** ![mnse](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mnse/32/16520_2.png) [@mnse](https://discourse.processing.org/u/mnse)\
**Post date:** [July 1, 2022, 4:51am UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/8 "2022-07-01T04:51:59Z")

</div>

Hi @asymmetric ,

As this initialize the terrain once depending on a static image, it should be placed in setup(). Afterwards the values of the terrain can be used in draw() to apply it to your grid and display it, but as it is static the grid can also be pre-defined in setup().

Cheers  
— mnse

---

<div class="post-metadata">

**Author:** ![asymmetric](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/asymmetric/32/16577_2.png) [@asymmetric](https://discourse.processing.org/u/asymmetric)\
**Post date:** [July 1, 2022, 5:54pm UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/9 "2022-07-01T17:54:26Z")

</div>

Hi mnse! I placed the code that @glv wrote under the setup(). I have also declared a variable of type PImage, but I am still getting the same image when I run the compiler? If you could expand on how to initialize the terrain and how to use the values of the terrain in draw() that would be very appreciated! 🙏

This is the code I have at the moment.

```auto
//VARIABLES
PImage img; // Declare a variable of type PImage
int cols,rows;
int scl = 8; //scale
int w = 1200;
int h = 900;

float[][] terrain;

//INITIALIZE
void setup(){
  size(1000,1000, P3D);  
  img = loadImage("Jan24.jpg");
  terrain = new float [img.width][img.height];
  img.loadPixels();
  for (int x = 0; x < img.width; x++) 
    {
    // Loop through every pixel row
    for (int y = 0; y < img.height; y++) 
      {
      // Use the formula to find the 1D location
      int loc = x + y * img.width;
      
      int bright = int(brightness(img.pixels[loc]));
      terrain[x][y] = bright;
      }
    }
  
  
  cols = w/ scl;  
  rows = h/ scl;
  terrain = new float [cols][rows];
  float yoff = 0;
  for (int y = 0; y < rows; y++) {
    float xoff = 0.2;
    beginShape(TRIANGLE_STRIP);
    for (int x = 0; x< cols; x++) {   
      terrain[x][y] = map(noise(xoff,yoff), 0, 1, -200, 50);
      xoff += 0.2;
    }
    yoff += 0.1;
  }
  
} 

//img.updatePixels(); //Not needed here

void draw(){
  background(0);
  stroke(255);
  smooth();
  noFill(); 
  //rect(x*scl, y*scl, scl, scl); // grid!!
  
  translate(width/2, height/2); //rotate perspective
  //rotateX(PI/3); //rotate perspective
  translate(-width/2,-height/2); //perspective 
 
  
  frameRate(1);
  
  for (int y = 0; y < rows-1; y++) {
    beginShape(QUAD_STRIP); // OR beginShape(QUAD_STRIP), (TRIANGLE_STRIP)
    for (int x = 0; x< cols; x++) {
      vertex(x*scl, y*scl, terrain[x][y]);
      vertex(x*scl, (y+1)*scl, terrain[x][y+1]);
      
       }
         endShape();
    }
}

```

---

<div class="post-metadata">

**Author:** ![mnse](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mnse/32/16520_2.png) [@mnse](https://discourse.processing.org/u/mnse)\
**Post date:** [July 1, 2022, 6:03pm UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/10 "2022-07-01T18:03:49Z")

</div>

Hi @asymmetric,

You are here overwriting the values again from above… 🙂

> [@asymmetric](#):
>
> ```auto
> terrain = new float [cols][rows];
> float yoff = 0;
> for (int y = 0; y < rows; y++) {
> float xoff = 0.2;
> beginShape(TRIANGLE_STRIP);
> for (int x = 0; x< cols; x++) {   
> terrain[x][y] = map(noise(xoff,yoff), 0, 1, -200, 50);
> xoff += 0.2;
> }
> yoff += 0.1;
> }
> 
> ```

Was quite busy with other work the last days. I’ll try to post a complete example for you tomorrow…

Cheers  
---- mnse

---

<div class="post-metadata">

**Author:** ![asymmetric](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/asymmetric/32/16577_2.png) [@asymmetric](https://discourse.processing.org/u/asymmetric)\
**Post date:** [July 1, 2022, 6:11pm UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/11 "2022-07-01T18:11:47Z")

</div>

Thank you, @mnse!! You’re the best! I’ll check back again! 🤩 💟

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [July 1, 2022, 9:29pm UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/12 "2022-07-01T21:29:25Z")

</div>

> [@asymmetric](#):
>
> if you would not mind uploading the full code that you used to get to that image, I would be immensely grateful!

Hello @asymmetric ,

I will not provide you with the full code; I wrote that code so I could offer assistance.

This is an achievable exercise and worth the effort on your part to work through and understand.

I did this myself before providing you with some direction, a “snippet” of code and references.

I encourage you to work through this and try to understand it; this time invested will pay off in the long run.

The Processing Forum Guidelines are here:

- [FAQ - Processing Foundation](https://discourse.processing.org/faq)
- [Guidelines—Asking Questions](https://discourse.processing.org/t/guidelines-asking-questions/2147)
- [Guidelines—Answering Questions](https://discourse.processing.org/t/guidelines-answering-questions/2145) \< There are four references to “full code” here.
- References to “full code” from the Guidelines - Answering Questions:

> [@Guidelines—Answering Questions](https://discourse.processing.org/t/guidelines-answering-questions/2145/1):
>
> The only way to learn it is by going through it: practice makes perfect! If you just post full code solutions, you’re taking that opportunity to practice away.

> [@Guidelines—Answering Questions](https://discourse.processing.org/t/guidelines-answering-questions/2145/1):
>
> Instead of offering a full code solution, try to walk the person through the process of solving their problem themselves

> [@Guidelines—Answering Questions](https://discourse.processing.org/t/guidelines-answering-questions/2145/1):
>
> Please **don’t** say things like this:
> 
> - Here’s a full code solution!

> [@Guidelines—Answering Questions](https://discourse.processing.org/t/guidelines-answering-questions/2145/1):
>
> Code examples (not full code solutions) with an explanation of how they’re helpful.

Processing website:

> **[Welcome to Processing!](https://processing.org/)**
>
> Processing is a flexible software sketchbook and a language for learning how to code. Since 2001, Processing has promoted software literacy within the visual arts and visual literacy within technology…

I do not want to take the opportunity away from you!

If you have specific questions please ask.

`:)`

---

<div class="post-metadata">

**Author:** ![mnse](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mnse/32/16520_2.png) [@mnse](https://discourse.processing.org/u/mnse)\
**Post date:** [July 2, 2022, 8:39am UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/13 "2022-07-02T08:39:38Z")

</div>

Hi @glv,

in principle I totally agree with you!  
Learning to code is a long process that never ends and that only works if you work hard at it and learn from your mistakes, **but** also from other people.  
However, regarding the latter, for many it is necessary to look at how others do it. First, to familiarize yourself with it, and second, to see if you understand the approach or not, and to question why someone implemented it the way they did. This also allows you, after you have studied it, to ask further questions and, in the best case, to develop your own and perhaps new approaches that will help you and, in turn, other people who learn from you.  
However, since I also understand the purpose of the guildlines you carefully selected, I’m a little torn about posting my finished example solution here. 😁

@asymmetric: Means, I think, I need some more time to came up with a final decission to post it or not … So, try first on your own to see if you get a result by @glv’s snippet and if you not came up with a solution for your own, let us know …

Cheers  
— mnse

EDIT: removed example output from here as posted completely below …

---

<div class="post-metadata">

**Author:** ![jafal](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jafal/32/19112_2.png) [@jafal](https://discourse.processing.org/u/jafal)\
**Post date:** [July 2, 2022, 2:50pm UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/14 "2022-07-02T14:50:43Z")

</div>

![Screenshot_2022-07-02-17-47-28-279](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/d/7/d74f0aff815db667058bdf40844c1467343f5949.jpeg)  
 ![Screenshot_2022-07-02-17-48-20-860](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/0/b/0bb1b47c751102d533542fd8de21d4945e4bd98c.jpeg)  
 ![Screenshot_2022-07-02-18-04-27-591](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/b/1/b1bff950243197e3850c8812574e6625322c96cd.jpeg)

---

<div class="post-metadata">

**Author:** ![mnse](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mnse/32/16520_2.png) [@mnse](https://discourse.processing.org/u/mnse)\
**Post date:** [July 2, 2022, 4:02pm UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/15 "2022-07-02T16:02:05Z")

</div>

Hi again,

Well, as the day is slowly coming to an end and I’ve had some thoughts about whether to post or not, I’ve come to the decision that I will post it after all.  
There are many pros and cons that could be listed, but none of them weigh so heavily that there would be a right or wrong.  
Reasons are …  
My code is just one of many examples and is far from an all-encompassing implementation. There are many things that can be worked out in addition to this on the topic.  
I’ve now added lots of comments to the code, to not offer this as a simple copy/paste solution, but rather that one can get an idea of what concrete was done here and most importantly why.  
(took longer than to code it. 😁)

If you disagree with my decision, you are free to flag the post. 😉

> **Code+Image**
>
> ```auto
> // a class to representing a point on our grid.
> // This should/would/could be done better by defining it as faces (of a triangle mesh).
> // but would it keep as simple as possible 
> class GridPoint {
> float x, y, v;
> public GridPoint(float px, float py, float pv) {
> x = px; // x-pos of the grid point
> y = py; // y-pos of the grid point
> v = pv; // height of the grid point
> }
> }
> 
> //helper variables
> float halfWidth, halfHeight;
> boolean mode = false;
> // storage of out grid
> int rows, cols;
> GridPoint[][] grid;
> // image used for texture and heightmap
> PImage img;
> 
> void setup() {
> size(800, 800, P3D);
> halfWidth = width/2.;
> halfHeight = height/2.;
> initGrid(10.);
> // use textureMode IMAGE as the grid is not normalized
> textureMode(IMAGE);
> }
> 
> void initGrid(float scl) {
> // load the image, used for texture and heightmap.
> // usually more than one picture will be used. One for heightmap, one for normalmap and one with the texture.
> // for simplicity it has the same size than our grid to not make the code more math intensive.
> // to get this work our image is somehow a bit blurred (like noise is), otherwise the mesh isn't smooth enough
> img = loadImage("image.png");
> img.loadPixels();
> // initialize our gridpoints
> rows = floor(height/scl);
> cols = floor(width/scl);
> grid= new GridPoint[rows][cols];
> for (int y = 0; y < rows; y++) {
> for (int x = 0; x < cols; x++) {
> int sx = floor(x*scl);
> int sy = floor(y*scl);
> // set x and y coordinates (center origin) and the height of the current point.
> // height is the normalized brightness value [0..1] of the pixel color from the image.
> // Subtract 0.5 to align it to center [-0.5..0.5]
> // scaling it by 50, so the range is [50.0*(-0.5)..50.0*(0.5)]
> grid[y][x] = new GridPoint(-halfWidth+sx+scl/2, -halfHeight+sy+scl/2, 50.*(brightness(img.get(sx, sy))/255-0.5));
> }
> }
> }
> 
> void draw() {
> background(0);
> // set the origin to the center of the screen, and move it 400px far away on z-axis
> translate(halfWidth, halfHeight, -400);
> 
> // switch between mesh and texured mode
> if (frameCount % int(TAU*100.) == 0) {
> mode = !mode;
> }
> 
> if (mode) {
> // if textured mode no strokes and a light from viewpoint to object
> noStroke();
> directionalLight(255, 255, 255, 0, 0, -1);
> } else {
> // if mesh mode only show strokes
> noFill();
> stroke(128);
> strokeWeight(0.5);
> }
> 
> // apply the rotation after lighting, otherwhile the light gets also rotated, which we not want.
> // tipping 30degree back on X-axis
> rotateX(radians(30));
> // tipping left/right a bit per frame from -PI/4 - +PI/4 on Y-axis
> rotateY(sin(frameCount/100.)*QUARTER_PI);
> 
> // build the surface/terrain by triangle strips to display it
> for (int y = 0; y < rows-1; y ++) {
> beginShape(TRIANGLE_STRIP);
> if (mode) {
> // on textured mode set the texture
> texture(img);
> }
> // common triangle strips
> for (int x = 0; x < cols; x++) {
> GridPoint ca = grid[y][x];
> GridPoint cb = grid[y+1][x];
> vertex(ca.x, ca.y, ca.v, ca.x+halfWidth, ca.y+halfHeight);
> if (mode) {
> // on textured mode we need to set the normal vector, so the light knows how to behave on hittng the surface
> // usually there are better calculation than this cheap hack
> // comment it out to see the difference if normals are messed up
> PVector na = new PVector(ca.x-cb.x, ca.y-cb.y, 0).sub(new PVector(ca.x-cb.x, ca.y-cb.y, 1)).normalize();
> normal(na.x, na.y, na.z);
> }
> vertex(cb.x, cb.y, cb.v, cb.x+halfWidth, cb.y+halfHeight);
> if (mode) {
> // on textured mode we need to set the normal vector, so the light knows how to behave on hittng the surface
> // usually there are better calculation than this cheap hack
> // comment it out to see the difference if normals are messed up
> PVector nb = new PVector(cb.x-ca.x, cb.y-ca.y, 0).sub(new PVector(cb.x-ca.x, cb.y-ca.y, 1)).normalize();
> normal(nb.x, nb.y, nb.z);
> }
> }
> endShape();
> }
> }
> 
> ```
> 
> Image used for code above [800x800]px
> 
> ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/f/4/f4caec351570dd0737c869958933719cc66d44c6.png)

Result:  
 ![output](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/a/3/a327ebc0df7dcabc3654e4fb89a32842db5876f3.webp)

Cheers  
— mnse

---

<div class="post-metadata">

**Author:** ![jafal](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jafal/32/19112_2.png) [@jafal](https://discourse.processing.org/u/jafal)\
**Post date:** [July 2, 2022, 4:35pm UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/16 "2022-07-02T16:35:32Z")

</div>

```auto
PImage img;
int cols, rows;
int scl = 26;
int w = 2800;
int h = 2600;

float ax, ay;

int videoScale =14;

int cols1, rows1;

//int sphereMy ;
void setup() {
  size(1200, 1000, OPENGL);
// rectMode(CENTER);
String http = "http://";
  //img = loadImage( http + "www.tfguy44.com/MyIcon1.PNG");

img = loadImage( "ee.jpeg");
 cols = w / scl;
  rows = h/ scl;
//cols1 = width/videoScale;
// rows1 = height/videoScale;
 rows1 = 222/videoScale;
 cols1 = 222/videoScale;
  texture(img);

}
 
void draw() {
  background(0);
 
  lights();
 
 translate(width/2, height/2, 0);
 
  scale(1.5);
  rotateY(map(mouseX, 0, width, -PI, PI));
  rotateX(-map(mouseY, 0, height, -PI, PI));
 
  //point(455, 434, 122);
  for (int u=0; u<1; u+=1) {
    sphereMy(20-u, 10-u, 111-u);
  }

 // stroke(255, 0, 0);
 // fill(255, 0, 0, 128);
// noStroke(); 
 noFill(); 
 stroke(255, 255, 255);
// fill(0, 0, 255, 128);
  plane();
 
 // stroke(0, 255, 0);
 // fill(0, 255, 0, 128);
  rotateX(HALF_PI);
 //noStroke(); 
// noFill(); 
stroke(255, 255, 255);
 //fill(0, 0, 255, 128);
  plane();
// NoStrok();
// noStroke(); 
// noFill(); 
 stroke(255, 255, 255);
//fill(255, 255, 255);
 rotateY(HALF_PI);
  plane();
}
 
void plane() {
  //for (int f=-6; f<7; f++) {
 // for (int c=-6; c<7; c++) {
     // rect(10*c, 10*f, 10, 10);
   for (int k = 0; k < cols1; k++) {
    // Begin loop for rows
    for (int j = 0; j < rows1; j++) {

      // Scaling up to draw a rectangle at (x,y)
      int g = k*videoScale;
      int t = j*videoScale;
     // fill(255);
      //stroke(0);
      // For every column and row, a rectangle is drawn at an (x,y) location scaled and sized by videoScale.
      rect(g, t, videoScale, videoScale); 
  
  

}
  }
}
//void sphereMy(float s, float d, float w) {
 void sphereMy(float l, float r, float e) {
 lights();
  

  background(4);
  
   
   pushMatrix();
  noStroke(); 
 // fill(255, 111, 11);
  translate(r, l, e); 
  sphere (2); 
 // translate(width/2, height/2);
 // rotateY(map(mouseX, 0, width, -PI, PI));
  //rotateX(map(mouseY, 0, width, -PI, PI));
 scale(0.07);

  translate(-w/12, -h/12);
  for (int y = 0; y < rows-1; y++) {
   
    beginShape(TRIANGLE_STRIP);
     
    texture(img);

    for (int x = 0; x < cols; x++) {
      ax = map(x, 0, cols, 0, img.width);
      ay = map(y, 0, rows, 0, img.height);

      vertex(x*scl, y*scl, map(brightness(img.get(int(ax), int(ay))), 320, 255, 0, 200), ax, ay );

      ax = map(x, 0, cols, 0, img.width);
      ay = map(y+1, 0, rows, 0, img.height);

      vertex(x*scl, (y+1)*scl, map(brightness(img.get(int(ax), int(ay))), 320, 255, 0, 200), ax, ay );
      //rect(x*scl, y*scl, scl, scl);
    }
    endShape();
  }
  
  
  
  
  popMatrix();
}

```

---

<div class="post-metadata">

**Author:** ![asymmetric](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/asymmetric/32/16577_2.png) [@asymmetric](https://discourse.processing.org/u/asymmetric)\
**Post date:** [July 2, 2022, 7:36pm UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/17 "2022-07-02T19:36:01Z")

</div>

Thank you, @mnse!! I really appreciate your help as well as the extra time you spent clarifying in the code comments. In the future, I would like to edit the actual grid into different shapes and varying geometric designs which will react in the same way to the underlying static image. With that being said, I will be studying the code that you sent me this week and trying to make sense of how you connected it all.

As a beginner, my first idea on how to connect the aesthetic of the Perlin noise grid to a static image was to combine the code of the tutorial with the example code: 2D image mapped to 3D. I am still having a disconnect between the two, but is it possible to also get similar results with the following code as well?

```auto
PImage img;

void setup(){
  size(900, 900, P3D);
  img = loadImage("Jan24.jpg");
  img.resize(900,900);
  
}

void draw() {
  background(#f1f1f1);
  fill(0);
  noStroke();
  sphereDetail(3);
  //ellipse(mouseX,mouseY,40,40);
  
  float tiles = 100;
  float tileSize = width/tiles;
  
  push();
  rotateY(radians(frameCount) );
  translate(width/2,height/2);
  
  for (int x = 0; x < tiles; x++) {
    for (int y = 0; y < tiles; y++) {
      
    color c = img.get(int(x*tileSize),int(y*tileSize));
    float b = map(brightness(c),0,255,01,0); 
    
    float z = map(b,0,1,-100,100);
    
    push();
    translate(x*tileSize - width/2,y*tileSize- height/2, z);
    sphere(tileSize*b);
    pop();
    
    
    }
    
  }
    
}

```

Thank you again! Your code is very helpful for me to bounce off and learn!! 💟 🤩

---

<div class="post-metadata">

**Author:** ![asymmetric](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/asymmetric/32/16577_2.png) [@asymmetric](https://discourse.processing.org/u/asymmetric)\
**Post date:** [July 2, 2022, 7:37pm UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/18 "2022-07-02T19:37:38Z")

</div>

![Screen Shot 2022-07-02 at 12.36.47 PM](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/0/a/0ae1351e426f61b1167c40a3b4dc259ffa570249.jpeg)  
Also, I played around with your code and edited it a bit! I’m so excited to keep editing and learning!

🤩

---

<div class="post-metadata">

**Author:** ![asymmetric](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/asymmetric/32/16577_2.png) [@asymmetric](https://discourse.processing.org/u/asymmetric)\
**Post date:** [July 2, 2022, 7:38pm UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/19 "2022-07-02T19:38:45Z")

</div>

Hi @jafal! I tried compiling your code but it doesn’t work for some reason? I’m interested in seeing the way you did it as well and learning more! Thank you so much!

---

<div class="post-metadata">

**Author:** ![jafal](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jafal/32/19112_2.png) [@jafal](https://discourse.processing.org/u/jafal)\
**Post date:** [July 2, 2022, 10:41pm UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/20 "2022-07-02T22:41:47Z")

</div>

@asymmetric

Hi

When I came to this forum my knowledge was less than zero about processing I read almost all entire forum and watched all processing videos all over internet now I have little experience to code what I want not that easy for me but I can hardly

Here you can meet very good experience people you can learn from them as I did

The sketch I provided isn’t mine I collected it from multi topics

> [@3 sketch in one](https://discourse.processing.org/t/3-sketch-in-one/29036/4):
>

---

<div class="post-metadata">

**Author:** ![mnse](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mnse/32/16520_2.png) [@mnse](https://discourse.processing.org/u/mnse)\
**Post date:** [July 3, 2022, 7:40am UTC](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770/21 "2022-07-03T07:40:20Z")

</div>

Hi @asymmetric,

> [@asymmetric](#):
>
> but is it possible to also get similar results with the following code as well?

if you remove the first push and do the translate before the rotate you are getting this (took my image instead as not having yours)… (see vid below)  
You can use the points (for which you’re currently adding spheres) also as gridpoints. If you afterwards connect it to a mesh it would do the same … so my answer would be, yes!

However, you can do whatever you want to do with that height information (There are so many possibilities to play around with it) depending on your imagination. 😉

Cheers  
— mnse

![output](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/b/c/bceab5f54ff1e697269c8f367b6006274e126a0f.webp)

[Next page](https://discourse.processing.org/t/3d-perlin-noise-in-processing/37770.md?page=2)
